⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vhdl.cpp

📁 一种将c高级语言转化给VHDL的编译器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* * LA-CC 05-135 Trident 0.7.1Copyright NoticeCopyright 2006 (c) the Regents of the University of California.This Software was produced under a U.S. Government contract(W-7405-ENG-36) by Los Alamos National Laboratory, which is operatedby the University of California for the U.S. Department of Energy. TheU.S. Government is licensed to use, reproduce, and distribute thisSoftware. Permission is granted to the public to copy and use thisSoftware without charge, provided that this Notice and any statementof authorship are reproduced on all copies. Neither the Government northe University makes any warranty, express or implied, or assumes anyliability or responsibility for the user of this Software. *///===-- Writer.cpp - Library for converting LLVM code to C ----------------===//// //                     The LLVM Compiler Infrastructure//// This file was developed by the LLVM research group and is distributed under// the University of Illinois Open Source License. See LICENSE.TXT for details.// //===----------------------------------------------------------------------===////// This library converts LLVM code to C code, compilable by GCC and other C// compilers.////===----------------------------------------------------------------------===//#include "VTargetMachine.h"#include "llvm/Constants.h"#include "llvm/DerivedTypes.h"#include "llvm/Module.h"#include "llvm/Instructions.h"#include "llvm/Pass.h"#include "llvm/PassManager.h"#include "llvm/SymbolTable.h"#include "llvm/Intrinsics.h"#include "llvm/Analysis/ConstantsScanner.h"#include "llvm/Analysis/FindUsedTypes.h"#include "llvm/Analysis/LoopInfo.h"#include "llvm/CodeGen/IntrinsicLowering.h"#include "llvm/Transforms/Scalar.h"#include "llvm/Target/TargetMachineRegistry.h"#include "llvm/Support/CallSite.h"#include "llvm/Support/CFG.h"#include "llvm/Support/GetElementPtrTypeIterator.h"#include "llvm/Support/InstVisitor.h"#include "llvm/Support/Mangler.h"#include "llvm/ADT/StringExtras.h"#include "llvm/Support/MathExtras.h"#include "llvm/Config/config.h"#include <algorithm>#include <iostream>#include <sstream>using namespace llvm;namespace {  //Register the target  RegisterTarget<VTargetMachine> X("v", "  VHDL backend");  /// NameAllUsedStructs - This pass inserts names for any unnamed structure  /// types that are used by the program.  ///  class VBackendNameAllUsedStructs : public ModulePass {    void getAnalysisUsage(AnalysisUsage &AU) const {      AU.addRequired<FindUsedTypes>();    }    virtual const char *getPassName() const {      return "V FloatIntermediate backend type canonicalizer";    }    virtual bool runOnModule(Module &M);  };  // VWriter - This class is for producing our own special textual  // represetation.  class VWriter : public FunctionPass, public InstVisitor<VWriter> {    std::ostream &Out;     IntrinsicLowering &IL;    Mangler *Mang;    LoopInfo *LI;    const Module *TheModule;    std::map<const Type *, std::string> TypeNames;    std::map<const ConstantFP *, unsigned> FPConstantMap;    int level;  public:    VWriter(std::ostream &o, IntrinsicLowering &il) : Out(o), IL(il) {}    virtual const char *getPassName() const { return "VHDL backend"; }    void getAnalysisUsage(AnalysisUsage &AU) const {      AU.addRequired<LoopInfo>();      AU.setPreservesAll();    }    virtual bool doInitialization(Module &M);    bool runOnFunction(Function &F) {      LI = &getAnalysis<LoopInfo>();      // First pass, lower all unhandled intrinsics.      lowerIntrinsics(F);      // Output all floating point constants ??? do we want this?      printFloatingPointConstants(F);            // Ensure that no local symbols conflict with global symbols      F.renameLocalSymbols();      printFunction(F);      FPConstantMap.clear();      return false;    }    virtual bool doFinalization(Module &M) {      // Free memory...      delete Mang;      TypeNames.clear();      return false;    }    std::ostream &printType(std::ostream &Out, const Type *Ty,                            const std::string &VariableName = "",                            bool IgnoreName = false);    void writeOperand(Value *Operand);    void writeOperandInternal(Value *Operand);  private :    void lowerIntrinsics(Function &F);    bool nameAllUsedStructureTypes(Module &M);    void printModule(Module *M);    void printModuleTypes(const SymbolTable &ST);    void printContainedStructs(const Type *Ty, std::set<const StructType *> &);    void printFloatingPointConstants(Function &F);    void printFunctionSignature(const Function *F, bool Prototype);    void printFunction(Function &);    void printBasicBlock(BasicBlock *BB);    void printLoop(Loop *L);    void printSpace();    void printConstant(Constant *CPV);    void printConstantArray(ConstantArray *CPA);    // isInlinableInst - Attempt to inline instructions into their uses to build    // trees as much as possible.  To do this, we have to consistently decide    // what is acceptable to inline, so that variable declarations don't get    // printed and an extra copy of the expr is not emitted.    //    static bool isInlinableInst(const Instruction &I) {      // Always inline setcc instructions, even if they are shared by multiple      // expressions.  GCC generates horrible code if we don't.      if (isa<SetCondInst>(I)) return true;      // Must be an expression, must be used exactly once.  If it is dead, we      // emit it inline where it would go.      if (I.getType() == Type::VoidTy || !I.hasOneUse() ||          isa<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I) ||           isa<LoadInst>(I) || isa<VAArgInst>(I) || isa<VANextInst>(I))        // Don't inline a load across a store or other bad things!        return false;      // Only inline instruction it it's use is in the same BB as the inst.      return I.getParent() == cast<Instruction>(I.use_back())->getParent();    }    // isDirectAlloca - Define fixed sized allocas in the entry block as direct    // variables which are accessed with the & operator.  This causes GCC to    // generate significantly better code than to emit alloca calls directly.    //    static const AllocaInst *isDirectAlloca(const Value *V) {      const AllocaInst *AI = dyn_cast<AllocaInst>(V);      if (!AI) return false;      if (AI->isArrayAllocation())        return 0;   // FIXME: we can also inline fixed size array allocas!      if (AI->getParent() != &AI->getParent()->getParent()->getEntryBlock())        return 0;      return AI;    }    // Instruction visitation functions    friend class InstVisitor<VWriter>;    void visitReturnInst(ReturnInst &I);    void visitBranchInst(BranchInst &I);    void visitSwitchInst(SwitchInst &I);    void visitInvokeInst(InvokeInst &I) {      assert(0 && "Lowerinvoke pass didn't work!");    }    void visitUnwindInst(UnwindInst &I) {      assert(0 && "Lowerinvoke pass didn't work!");    }    void visitPHINode(PHINode &I);    void visitBinaryOperator(Instruction &I);    void visitCastInst (CastInst &I);    void visitSelectInst(SelectInst &I);    void visitCallInst (CallInst &I);    void visitCallSite (CallSite CS);    void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }    void visitMallocInst(MallocInst &I);    void visitAllocaInst(AllocaInst &I);    void visitFreeInst  (FreeInst   &I);    void visitLoadInst  (LoadInst   &I);    void visitStoreInst (StoreInst  &I);    void visitGetElementPtrInst(GetElementPtrInst &I);    void visitVANextInst(VANextInst &I);    void visitVAArgInst (VAArgInst &I);    void visitInstruction(Instruction &I) {      std::cerr << "C Writer does not know about " << I;      abort();    }    void outputLValue(Instruction *I) {      Out << "  " << Mang->getValueName(I) << " = ";    }        bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To);    void printPHICopiesForSuccessors(BasicBlock *CurBlock,                                      unsigned Indent);    void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,                            unsigned Indent);    void printIndexingExpression(Value *Ptr, gep_type_iterator I,                                 gep_type_iterator E);  };}/// This method inserts names for any unnamed structure types that are used by/// the program, and removes names from structure types that are not used by /// the program.///bool VBackendNameAllUsedStructs::runOnModule(Module &M) {  // Get a set of types that are used by the program...  std::set<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes();    // Loop over the module symbol table, removing types from UT that are  // already named, and removing names for structure types that are not used.  //  SymbolTable &MST = M.getSymbolTable();  for (SymbolTable::type_iterator TI = MST.type_begin(), TE = MST.type_end();       TI != TE; ) {    SymbolTable::type_iterator I = TI++;    if (const StructType *STy = dyn_cast<StructType>(I->second)) {      // If this is not used, remove it from the symbol table.      std::set<const Type *>::iterator UTI = UT.find(STy);      if (UTI == UT.end())        MST.remove(I);      else        UT.erase(UTI);    }  }  // UT now contains types that are not named.  Loop over it, naming  // structure types.  //  bool Changed = false;  unsigned RenameCounter = 0;  for (std::set<const Type *>::const_iterator I = UT.begin(), E = UT.end();       I != E; ++I)    if (const StructType *ST = dyn_cast<StructType>(*I)) {      while (M.addTypeName("unnamed"+utostr(RenameCounter), ST))        ++RenameCounter;      Changed = true;    }  return Changed;}// Pass the Type* and the variable name and this prints out the variable// declaration.//std::ostream &VWriter::printType(std::ostream &Out, const Type *Ty,                                 const std::string &NameSoFar,                                 bool IgnoreName) {  if (Ty->isPrimitiveType())    switch (Ty->getTypeID()) {    case Type::VoidTyID:   return Out << "void "               << NameSoFar;    case Type::BoolTyID:   return Out << "bool "               << NameSoFar;    case Type::UByteTyID:  return Out << "ubyte "      << NameSoFar;    case Type::SByteTyID:  return Out << "sbyte "        << NameSoFar;    case Type::UShortTyID: return Out << "ushort "     << NameSoFar;    case Type::ShortTyID:  return Out << "short "              << NameSoFar;    case Type::UIntTyID:   return Out << "uint "           << NameSoFar;    case Type::IntTyID:    return Out << "int "                << NameSoFar;    case Type::ULongTyID:  return Out << "ulong " << NameSoFar;    case Type::LongTyID:   return Out << "long "   << NameSoFar;    case Type::FloatTyID:  return Out << "float "              << NameSoFar;    case Type::DoubleTyID: return Out << "double "             << NameSoFar;    default :      std::cerr << "Unknown primitive type: " << *Ty << "\n";      abort();    }    // Check to see if the type is named.  if (!IgnoreName || isa<OpaqueType>(Ty)) {    std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty);    if (I != TypeNames.end()) return Out << I->second << " " << NameSoFar;  }  switch (Ty->getTypeID()) {  case Type::FunctionTyID: {    const FunctionType *MTy = cast<FunctionType>(Ty);    std::stringstream FunctionInnards;     FunctionInnards << " (" << NameSoFar << ") (";    for (FunctionType::param_iterator I = MTy->param_begin(),           E = MTy->param_end(); I != E; ++I) {      if (I != MTy->param_begin())        FunctionInnards << ", ";      printType(FunctionInnards, *I, "");    }    if (MTy->isVarArg()) {      if (MTy->getNumParams())     	FunctionInnards << ", ...";    } else if (!MTy->getNumParams()) {      FunctionInnards << "void";    }    FunctionInnards << ")";    std::string tstr = FunctionInnards.str();    printType(Out, MTy->getReturnType(), tstr);    return Out;  }  case Type::StructTyID: {    const StructType *STy = cast<StructType>(Ty);    Out << NameSoFar + " {\n";    unsigned Idx = 0;    for (StructType::element_iterator I = STy->element_begin(),           E = STy->element_end(); I != E; ++I) {      Out << "  ";      printType(Out, *I, "field" + utostr(Idx++));      Out << ";\n";    }    return Out << "}";  }    case Type::PointerTyID: {    const PointerType *PTy = cast<PointerType>(Ty);    std::string ptrName = "*" + NameSoFar;    if (isa<ArrayType>(PTy->getElementType()))      ptrName = "(" + ptrName + ")";    return printType(Out, PTy->getElementType(), ptrName);  }  case Type::ArrayTyID: {    const ArrayType *ATy = cast<ArrayType>(Ty);    unsigned NumElements = ATy->getNumElements();    return printType(Out, ATy->getElementType(),                     NameSoFar + "[" + utostr(NumElements) + "]");  }  case Type::OpaqueTyID: {    static int Count = 0;    std::string TyName = "struct opaque_" + itostr(Count++);    assert(TypeNames.find(Ty) == TypeNames.end());    TypeNames[Ty] = TyName;    return Out << TyName << " " << NameSoFar;  }  default:    assert(0 && "Unhandled case in getTypeProps!");    abort();  }  return Out;}void VWriter::printConstantArray(ConstantArray *CPA) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -