| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 1 | //===-- MSILWriter.h - TargetMachine for the MSIL ---------------*- C++ -*-===// | 
|  | 2 | // | 
| Anton Korobeynikov | fb80151 | 2007-04-16 18:10:23 +0000 | [diff] [blame] | 3 | //                     The LLVM Compiler Infrastructure | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 4 | // | 
|  | 5 | // This file was developed by Roman Samoilov and is distributed under | 
|  | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file declares the MSILWriter that is used by the MSIL. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 | #ifndef MSILWRITER_H | 
|  | 14 | #define MSILWRITER_H | 
|  | 15 |  | 
|  | 16 | #include "llvm/Constants.h" | 
|  | 17 | #include "llvm/Module.h" | 
|  | 18 | #include "llvm/Instructions.h" | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 19 | #include "llvm/IntrinsicInst.h" | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 20 | #include "llvm/Pass.h" | 
|  | 21 | #include "llvm/PassManager.h" | 
|  | 22 | #include "llvm/Analysis/FindUsedTypes.h" | 
|  | 23 | #include "llvm/Analysis/LoopInfo.h" | 
|  | 24 | #include "llvm/Support/GetElementPtrTypeIterator.h" | 
|  | 25 | #include "llvm/Target/TargetData.h" | 
|  | 26 | #include "llvm/Target/TargetMachine.h" | 
|  | 27 | #include "llvm/Target/TargetMachineRegistry.h" | 
|  | 28 | #include "llvm/Support/Mangler.h" | 
|  | 29 | #include <algorithm> | 
|  | 30 | #include <ios> | 
|  | 31 | using namespace llvm; | 
|  | 32 |  | 
|  | 33 | namespace { | 
|  | 34 |  | 
|  | 35 | class MSILModule : public ModulePass { | 
|  | 36 | Module *ModulePtr; | 
|  | 37 | const std::set<const Type *>*& UsedTypes; | 
|  | 38 | const TargetData*& TD; | 
|  | 39 |  | 
|  | 40 | public: | 
| Devang Patel | 8c78a0b | 2007-05-03 01:11:54 +0000 | [diff] [blame] | 41 | static char ID; | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 42 | MSILModule(const std::set<const Type *>*& _UsedTypes, | 
|  | 43 | const TargetData*& _TD) | 
| Devang Patel | 09f162c | 2007-05-01 21:15:47 +0000 | [diff] [blame] | 44 | : ModulePass((intptr_t)&ID), UsedTypes(_UsedTypes), TD(_TD) {} | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 45 |  | 
|  | 46 | void getAnalysisUsage(AnalysisUsage &AU) const { | 
|  | 47 | AU.addRequired<FindUsedTypes>(); | 
|  | 48 | AU.addRequired<TargetData>(); | 
|  | 49 | } | 
|  | 50 |  | 
|  | 51 | virtual const char *getPassName() const { | 
|  | 52 | return "MSIL backend definitions"; | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 | virtual bool runOnModule(Module &M); | 
|  | 56 |  | 
|  | 57 | }; | 
|  | 58 |  | 
|  | 59 | class MSILWriter  : public FunctionPass { | 
|  | 60 | struct StaticInitializer { | 
|  | 61 | const Constant* constant; | 
|  | 62 | uint64_t offset; | 
|  | 63 |  | 
|  | 64 | StaticInitializer() | 
|  | 65 | : constant(0), offset(0) {} | 
|  | 66 |  | 
|  | 67 | StaticInitializer(const Constant* _constant, uint64_t _offset) | 
|  | 68 | : constant(_constant), offset(_offset) {} | 
|  | 69 | }; | 
|  | 70 |  | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 71 | uint64_t UniqID; | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 72 |  | 
|  | 73 | uint64_t getUniqID() { | 
|  | 74 | return ++UniqID; | 
|  | 75 | } | 
|  | 76 |  | 
|  | 77 | public: | 
|  | 78 | std::ostream &Out; | 
|  | 79 | Module* ModulePtr; | 
|  | 80 | const TargetData* TD; | 
|  | 81 | Mangler* Mang; | 
|  | 82 | LoopInfo *LInfo; | 
|  | 83 | std::vector<StaticInitializer>* InitListPtr; | 
|  | 84 | std::map<const GlobalVariable*,std::vector<StaticInitializer> > | 
|  | 85 | StaticInitList; | 
|  | 86 | const std::set<const Type *>* UsedTypes; | 
| Devang Patel | 8c78a0b | 2007-05-03 01:11:54 +0000 | [diff] [blame] | 87 | static char ID; | 
| Devang Patel | 09f162c | 2007-05-01 21:15:47 +0000 | [diff] [blame] | 88 | MSILWriter(std::ostream &o) : FunctionPass((intptr_t)&ID), Out(o) { | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 89 | UniqID = 0; | 
|  | 90 | } | 
|  | 91 |  | 
|  | 92 | enum ValueType { | 
|  | 93 | UndefVT, | 
|  | 94 | GlobalVT, | 
|  | 95 | InternalVT, | 
|  | 96 | ArgumentVT, | 
|  | 97 | LocalVT, | 
|  | 98 | ConstVT, | 
|  | 99 | ConstExprVT | 
|  | 100 | }; | 
|  | 101 |  | 
|  | 102 | bool isVariable(ValueType V) { | 
|  | 103 | return V==GlobalVT || V==InternalVT || V==ArgumentVT || V==LocalVT; | 
|  | 104 | } | 
|  | 105 |  | 
|  | 106 | bool isConstValue(ValueType V) { | 
|  | 107 | return V==ConstVT || V==ConstExprVT; | 
|  | 108 | } | 
|  | 109 |  | 
|  | 110 | virtual const char *getPassName() const { return "MSIL backend"; } | 
|  | 111 |  | 
|  | 112 | void getAnalysisUsage(AnalysisUsage &AU) const { | 
|  | 113 | AU.addRequired<LoopInfo>(); | 
|  | 114 | AU.setPreservesAll(); | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | bool runOnFunction(Function &F); | 
|  | 118 |  | 
|  | 119 | virtual bool doInitialization(Module &M); | 
|  | 120 |  | 
|  | 121 | virtual bool doFinalization(Module &M); | 
|  | 122 |  | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 123 | void printModuleStartup(); | 
|  | 124 |  | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 125 | bool isZeroValue(const Value* V); | 
|  | 126 |  | 
|  | 127 | std::string getValueName(const Value* V); | 
|  | 128 |  | 
|  | 129 | std::string getLabelName(const Value* V); | 
|  | 130 |  | 
|  | 131 | std::string getLabelName(const std::string& Name); | 
|  | 132 |  | 
|  | 133 | std::string getConvModopt(unsigned CallingConvID); | 
|  | 134 |  | 
|  | 135 | std::string getArrayTypeName(Type::TypeID TyID, const Type* Ty); | 
|  | 136 |  | 
|  | 137 | std::string getPrimitiveTypeName(const Type* Ty, bool isSigned); | 
|  | 138 |  | 
|  | 139 | std::string getFunctionTypeName(const Type* Ty); | 
|  | 140 |  | 
|  | 141 | std::string getPointerTypeName(const Type* Ty); | 
|  | 142 |  | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 143 | std::string getTypeName(const Type* Ty, bool isSigned = false, | 
|  | 144 | bool isNested = false); | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 145 |  | 
|  | 146 | ValueType getValueLocation(const Value* V); | 
|  | 147 |  | 
|  | 148 | std::string getTypePostfix(const Type* Ty, bool Expand, | 
|  | 149 | bool isSigned = false); | 
|  | 150 |  | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 151 | void printConvToPtr(); | 
|  | 152 |  | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 153 | void printPtrLoad(uint64_t N); | 
|  | 154 |  | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 155 | void printValuePtrLoad(const Value* V); | 
|  | 156 |  | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 157 | void printConstLoad(const Constant* C); | 
|  | 158 |  | 
|  | 159 | void printValueLoad(const Value* V); | 
|  | 160 |  | 
|  | 161 | void printValueSave(const Value* V); | 
|  | 162 |  | 
|  | 163 | void printBinaryInstruction(const char* Name, const Value* Left, | 
|  | 164 | const Value* Right); | 
|  | 165 |  | 
|  | 166 | void printSimpleInstruction(const char* Inst, const char* Operand = NULL); | 
|  | 167 |  | 
|  | 168 | void printPHICopy(const BasicBlock* Src, const BasicBlock* Dst); | 
|  | 169 |  | 
|  | 170 | void printBranchToBlock(const BasicBlock* CurrBB, | 
|  | 171 | const BasicBlock* TrueBB, | 
|  | 172 | const BasicBlock* FalseBB); | 
|  | 173 |  | 
|  | 174 | void printBranchInstruction(const BranchInst* Inst); | 
|  | 175 |  | 
|  | 176 | void printSelectInstruction(const Value* Cond, const Value* VTrue, | 
|  | 177 | const Value* VFalse); | 
|  | 178 |  | 
|  | 179 | void printIndirectLoad(const Value* V); | 
|  | 180 |  | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 181 | void printIndirectSave(const Value* Ptr, const Value* Val); | 
|  | 182 |  | 
|  | 183 | void printIndirectSave(const Type* Ty); | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 184 |  | 
|  | 185 | void printCastInstruction(unsigned int Op, const Value* V, | 
|  | 186 | const Type* Ty); | 
|  | 187 |  | 
|  | 188 | void printGepInstruction(const Value* V, gep_type_iterator I, | 
|  | 189 | gep_type_iterator E); | 
|  | 190 |  | 
|  | 191 | std::string getCallSignature(const FunctionType* Ty, | 
|  | 192 | const Instruction* Inst, | 
|  | 193 | std::string Name); | 
|  | 194 |  | 
|  | 195 | void printFunctionCall(const Value* FnVal, const Instruction* Inst); | 
|  | 196 |  | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 197 | void printIntrinsicCall(const IntrinsicInst* Inst); | 
|  | 198 |  | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 199 | void printCallInstruction(const Instruction* Inst); | 
|  | 200 |  | 
|  | 201 | void printICmpInstruction(unsigned Predicate, const Value* Left, | 
|  | 202 | const Value* Right); | 
|  | 203 |  | 
|  | 204 | void printFCmpInstruction(unsigned Predicate, const Value* Left, | 
|  | 205 | const Value* Right); | 
|  | 206 |  | 
|  | 207 | void printInvokeInstruction(const InvokeInst* Inst); | 
|  | 208 |  | 
|  | 209 | void printSwitchInstruction(const SwitchInst* Inst); | 
|  | 210 |  | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 211 | void printVAArgInstruction(const VAArgInst* Inst); | 
|  | 212 |  | 
|  | 213 | void printAllocaInstruction(const AllocaInst* Inst); | 
|  | 214 |  | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 215 | void printInstruction(const Instruction* Inst); | 
|  | 216 |  | 
|  | 217 | void printLoop(const Loop* L); | 
|  | 218 |  | 
|  | 219 | void printBasicBlock(const BasicBlock* BB); | 
|  | 220 |  | 
|  | 221 | void printLocalVariables(const Function& F); | 
|  | 222 |  | 
|  | 223 | void printFunctionBody(const Function& F); | 
|  | 224 |  | 
|  | 225 | void printConstantExpr(const ConstantExpr* CE); | 
|  | 226 |  | 
|  | 227 | void printStaticInitializerList(); | 
|  | 228 |  | 
|  | 229 | void printFunction(const Function& F); | 
|  | 230 |  | 
|  | 231 | void printDeclarations(const TypeSymbolTable& ST); | 
|  | 232 |  | 
|  | 233 | unsigned int getBitWidth(const Type* Ty); | 
|  | 234 |  | 
|  | 235 | void printStaticConstant(const Constant* C, uint64_t& Offset); | 
|  | 236 |  | 
|  | 237 | void printStaticInitializer(const Constant* C, const std::string& Name); | 
|  | 238 |  | 
|  | 239 | void printVariableDefinition(const GlobalVariable* G); | 
|  | 240 |  | 
|  | 241 | void printGlobalVariables(); | 
|  | 242 |  | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 243 | const char* getLibraryName(const Function* F); | 
|  | 244 |  | 
|  | 245 | const char* getLibraryName(const GlobalVariable* GV); | 
|  | 246 |  | 
|  | 247 | const char* getLibraryForSymbol(const char* Name, bool isFunction, | 
|  | 248 | unsigned CallingConv); | 
|  | 249 |  | 
| Anton Korobeynikov | aa3090d | 2007-03-21 21:38:25 +0000 | [diff] [blame] | 250 | void printExternals(); | 
|  | 251 | }; | 
|  | 252 | } | 
|  | 253 |  | 
|  | 254 | #endif | 
| Anton Korobeynikov | c892cf4 | 2007-05-06 20:13:33 +0000 | [diff] [blame] | 255 |  |