Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceConverter.cpp - Converts LLVM to Ice ---------------===// | 1 //===- subzero/src/IceConverter.cpp - Converts LLVM to Ice ---------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the LLVM to ICE converter. | 10 // This file implements the LLVM to ICE converter. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 #include "IceConverter.h" | 27 #include "IceConverter.h" |
| 28 #include "IceDefs.h" | 28 #include "IceDefs.h" |
| 29 #include "IceGlobalContext.h" | 29 #include "IceGlobalContext.h" |
| 30 #include "IceGlobalInits.h" | 30 #include "IceGlobalInits.h" |
| 31 #include "IceInst.h" | 31 #include "IceInst.h" |
| 32 #include "IceOperand.h" | 32 #include "IceOperand.h" |
| 33 #include "IceTargetLowering.h" | 33 #include "IceTargetLowering.h" |
| 34 #include "IceTypes.h" | 34 #include "IceTypes.h" |
| 35 #include "IceTypeConverter.h" | 35 #include "IceTypeConverter.h" |
| 36 | 36 |
| 37 // TODO(kschimpf): Remove two namespaces being visible at once. | |
| 37 using namespace llvm; | 38 using namespace llvm; |
| 38 | 39 |
| 39 namespace { | 40 namespace { |
| 40 | 41 |
| 41 // Debugging helper | 42 // Debugging helper |
| 42 template <typename T> static std::string LLVMObjectAsString(const T *O) { | 43 template <typename T> static std::string LLVMObjectAsString(const T *O) { |
| 43 std::string Dump; | 44 std::string Dump; |
| 44 raw_string_ostream Stream(Dump); | 45 raw_string_ostream Stream(Dump); |
| 45 O->print(Stream); | 46 O->print(Stream); |
| 46 return Stream.str(); | 47 return Stream.str(); |
| 47 } | 48 } |
| 48 | 49 |
| 49 // Base class for converting LLVM to ICE. | 50 // Base class for converting LLVM to ICE. |
| 50 class LLVM2ICEConverter { | 51 class LLVM2ICEConverter { |
| 51 LLVM2ICEConverter(const LLVM2ICEConverter &) = delete; | 52 LLVM2ICEConverter(const LLVM2ICEConverter &) = delete; |
| 52 LLVM2ICEConverter &operator=(const LLVM2ICEConverter &) = delete; | 53 LLVM2ICEConverter &operator=(const LLVM2ICEConverter &) = delete; |
| 53 | 54 |
| 54 public: | 55 public: |
| 55 LLVM2ICEConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext) | 56 LLVM2ICEConverter(Ice::Converter &Converter) |
| 56 : Ctx(Ctx), TypeConverter(LLVMContext) {} | 57 : Converter(Converter), Ctx(Converter.getContext()), |
| 58 TypeConverter(Converter.getModule()->getContext()) {} | |
| 59 | |
| 60 Ice::Converter &getConverter() const { return Converter; } | |
| 57 | 61 |
| 58 protected: | 62 protected: |
| 59 // Data | 63 Ice::Converter &Converter; |
| 60 Ice::GlobalContext *Ctx; | 64 Ice::GlobalContext *Ctx; |
| 61 const Ice::TypeConverter TypeConverter; | 65 const Ice::TypeConverter TypeConverter; |
| 62 }; | 66 }; |
| 63 | 67 |
| 64 // Converter from LLVM functions to ICE. The entry point is the | 68 // Converter from LLVM functions to ICE. The entry point is the |
| 65 // convertFunction method. | 69 // convertFunction method. |
| 66 // | 70 // |
| 67 // Note: this currently assumes that the given IR was verified to be | 71 // Note: this currently assumes that the given IR was verified to be |
| 68 // valid PNaCl bitcode. Otherwise, the behavior is undefined. | 72 // valid PNaCl bitcode. Otherwise, the behavior is undefined. |
| 69 class LLVM2ICEFunctionConverter : LLVM2ICEConverter { | 73 class LLVM2ICEFunctionConverter : LLVM2ICEConverter { |
| 70 LLVM2ICEFunctionConverter(const LLVM2ICEFunctionConverter &) = delete; | 74 LLVM2ICEFunctionConverter(const LLVM2ICEFunctionConverter &) = delete; |
| 71 LLVM2ICEFunctionConverter & | 75 LLVM2ICEFunctionConverter & |
| 72 operator=(const LLVM2ICEFunctionConverter &) = delete; | 76 operator=(const LLVM2ICEFunctionConverter &) = delete; |
| 73 | 77 |
| 74 public: | 78 public: |
| 75 LLVM2ICEFunctionConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext) | 79 LLVM2ICEFunctionConverter(Ice::Converter &Converter) |
| 76 : LLVM2ICEConverter(Ctx, LLVMContext), Func(NULL) {} | 80 : LLVM2ICEConverter(Converter), Func(nullptr) {} |
| 77 | 81 |
| 78 // Caller is expected to delete the returned Ice::Cfg object. | 82 // Caller is expected to delete the returned Ice::Cfg object. |
| 79 Ice::Cfg *convertFunction(const Function *F) { | 83 Ice::Cfg *convertFunction(const Function *F) { |
| 80 VarMap.clear(); | 84 VarMap.clear(); |
| 81 NodeMap.clear(); | 85 NodeMap.clear(); |
| 82 Func = new Ice::Cfg(Ctx); | 86 Func = new Ice::Cfg(Ctx); |
| 83 Func->setFunctionName(F->getName()); | 87 Func->setFunctionName(F->getName()); |
| 84 Func->setReturnType(convertToIceType(F->getReturnType())); | 88 Func->setReturnType(convertToIceType(F->getReturnType())); |
| 85 Func->setInternal(F->hasInternalLinkage()); | 89 Func->setInternal(F->hasInternalLinkage()); |
| 86 Ice::TimerMarker T(Ice::TimerStack::TT_llvmConvert, Func); | 90 Ice::TimerMarker T(Ice::TimerStack::TT_llvmConvert, Func); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 } else { | 123 } else { |
| 120 return Ctx->getConstantInt32(Ty, CI->getSExtValue()); | 124 return Ctx->getConstantInt32(Ty, CI->getSExtValue()); |
| 121 } | 125 } |
| 122 } else if (const auto CFP = dyn_cast<ConstantFP>(Const)) { | 126 } else if (const auto CFP = dyn_cast<ConstantFP>(Const)) { |
| 123 Ice::Type Type = convertToIceType(CFP->getType()); | 127 Ice::Type Type = convertToIceType(CFP->getType()); |
| 124 if (Type == Ice::IceType_f32) | 128 if (Type == Ice::IceType_f32) |
| 125 return Ctx->getConstantFloat(CFP->getValueAPF().convertToFloat()); | 129 return Ctx->getConstantFloat(CFP->getValueAPF().convertToFloat()); |
| 126 else if (Type == Ice::IceType_f64) | 130 else if (Type == Ice::IceType_f64) |
| 127 return Ctx->getConstantDouble(CFP->getValueAPF().convertToDouble()); | 131 return Ctx->getConstantDouble(CFP->getValueAPF().convertToDouble()); |
| 128 llvm_unreachable("Unexpected floating point type"); | 132 llvm_unreachable("Unexpected floating point type"); |
| 129 return NULL; | 133 return nullptr; |
| 130 } else if (const auto CU = dyn_cast<UndefValue>(Const)) { | 134 } else if (const auto CU = dyn_cast<UndefValue>(Const)) { |
| 131 return Ctx->getConstantUndef(convertToIceType(CU->getType())); | 135 return Ctx->getConstantUndef(convertToIceType(CU->getType())); |
| 132 } else { | 136 } else { |
| 133 llvm_unreachable("Unhandled constant type"); | 137 llvm_unreachable("Unhandled constant type"); |
| 134 return NULL; | 138 return nullptr; |
| 135 } | 139 } |
| 136 } | 140 } |
| 137 | 141 |
| 138 private: | 142 private: |
| 139 // LLVM values (instructions, etc.) are mapped directly to ICE variables. | 143 // LLVM values (instructions, etc.) are mapped directly to ICE variables. |
| 140 // mapValueToIceVar has a version that forces an ICE type on the variable, | 144 // mapValueToIceVar has a version that forces an ICE type on the variable, |
| 141 // and a version that just uses convertToIceType on V. | 145 // and a version that just uses convertToIceType on V. |
| 142 Ice::Variable *mapValueToIceVar(const Value *V, Ice::Type IceTy) { | 146 Ice::Variable *mapValueToIceVar(const Value *V, Ice::Type IceTy) { |
| 143 if (IceTy == Ice::IceType_void) | 147 if (IceTy == Ice::IceType_void) |
| 144 return NULL; | 148 return nullptr; |
| 145 if (VarMap.find(V) == VarMap.end()) { | 149 if (VarMap.find(V) == VarMap.end()) { |
| 146 VarMap[V] = Func->makeVariable(IceTy, V->getName()); | 150 VarMap[V] = Func->makeVariable(IceTy, V->getName()); |
| 147 } | 151 } |
| 148 return VarMap[V]; | 152 return VarMap[V]; |
| 149 } | 153 } |
| 150 | 154 |
| 151 Ice::Variable *mapValueToIceVar(const Value *V) { | 155 Ice::Variable *mapValueToIceVar(const Value *V) { |
| 152 return mapValueToIceVar(V, convertToIceType(V->getType())); | 156 return mapValueToIceVar(V, convertToIceType(V->getType())); |
| 153 } | 157 } |
| 154 | 158 |
| 155 Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) { | 159 Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) { |
| 156 if (NodeMap.find(BB) == NodeMap.end()) { | 160 if (NodeMap.find(BB) == NodeMap.end()) { |
| 157 NodeMap[BB] = Func->makeNode(BB->getName()); | 161 NodeMap[BB] = Func->makeNode(BB->getName()); |
| 158 } | 162 } |
| 159 return NodeMap[BB]; | 163 return NodeMap[BB]; |
| 160 } | 164 } |
| 161 | 165 |
| 162 Ice::Type convertToIceType(Type *LLVMTy) const { | 166 Ice::Type convertToIceType(Type *LLVMTy) const { |
| 163 Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy); | 167 Ice::Type IceTy = TypeConverter.convertToIceType(LLVMTy); |
| 164 if (IceTy == Ice::IceType_NUM) | 168 if (IceTy == Ice::IceType_NUM) |
| 165 report_fatal_error(std::string("Invalid PNaCl type ") + | 169 report_fatal_error(std::string("Invalid PNaCl type ") + |
| 166 LLVMObjectAsString(LLVMTy)); | 170 LLVMObjectAsString(LLVMTy)); |
| 167 return IceTy; | 171 return IceTy; |
| 168 } | 172 } |
| 169 | 173 |
| 170 // Given an LLVM instruction and an operand number, produce the | 174 // Given an LLVM instruction and an operand number, produce the |
| 171 // Ice::Operand this refers to. If there's no such operand, return | 175 // Ice::Operand this refers to. If there's no such operand, return |
| 172 // NULL. | 176 // nullptr. |
| 173 Ice::Operand *convertOperand(const Instruction *Inst, unsigned OpNum) { | 177 Ice::Operand *convertOperand(const Instruction *Inst, unsigned OpNum) { |
| 174 if (OpNum >= Inst->getNumOperands()) { | 178 if (OpNum >= Inst->getNumOperands()) { |
| 175 return NULL; | 179 return nullptr; |
| 176 } | 180 } |
| 177 const Value *Op = Inst->getOperand(OpNum); | 181 const Value *Op = Inst->getOperand(OpNum); |
| 178 return convertValue(Op); | 182 return convertValue(Op); |
| 179 } | 183 } |
| 180 | 184 |
| 181 Ice::Operand *convertValue(const Value *Op) { | 185 Ice::Operand *convertValue(const Value *Op) { |
| 182 if (const auto Const = dyn_cast<Constant>(Op)) { | 186 if (const auto Const = dyn_cast<Constant>(Op)) { |
| 183 return convertConstant(Const); | 187 return convertConstant(Const); |
| 184 } else { | 188 } else { |
| 185 return mapValueToIceVar(Op); | 189 return mapValueToIceVar(Op); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 case Instruction::Alloca: | 289 case Instruction::Alloca: |
| 286 return convertAllocaInstruction(cast<AllocaInst>(Inst)); | 290 return convertAllocaInstruction(cast<AllocaInst>(Inst)); |
| 287 case Instruction::Unreachable: | 291 case Instruction::Unreachable: |
| 288 return convertUnreachableInstruction(cast<UnreachableInst>(Inst)); | 292 return convertUnreachableInstruction(cast<UnreachableInst>(Inst)); |
| 289 default: | 293 default: |
| 290 report_fatal_error(std::string("Invalid PNaCl instruction: ") + | 294 report_fatal_error(std::string("Invalid PNaCl instruction: ") + |
| 291 LLVMObjectAsString(Inst)); | 295 LLVMObjectAsString(Inst)); |
| 292 } | 296 } |
| 293 | 297 |
| 294 llvm_unreachable("convertInstruction"); | 298 llvm_unreachable("convertInstruction"); |
| 295 return NULL; | 299 return nullptr; |
| 296 } | 300 } |
| 297 | 301 |
| 298 Ice::Inst *convertLoadInstruction(const LoadInst *Inst) { | 302 Ice::Inst *convertLoadInstruction(const LoadInst *Inst) { |
| 299 Ice::Operand *Src = convertOperand(Inst, 0); | 303 Ice::Operand *Src = convertOperand(Inst, 0); |
| 300 Ice::Variable *Dest = mapValueToIceVar(Inst); | 304 Ice::Variable *Dest = mapValueToIceVar(Inst); |
| 301 return Ice::InstLoad::create(Func, Dest, Src); | 305 return Ice::InstLoad::create(Func, Dest, Src); |
| 302 } | 306 } |
| 303 | 307 |
| 304 Ice::Inst *convertStoreInstruction(const StoreInst *Inst) { | 308 Ice::Inst *convertStoreInstruction(const StoreInst *Inst) { |
| 305 Ice::Operand *Addr = convertOperand(Inst, 1); | 309 Ice::Operand *Addr = convertOperand(Inst, 1); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 517 } | 521 } |
| 518 return Switch; | 522 return Switch; |
| 519 } | 523 } |
| 520 | 524 |
| 521 Ice::Inst *convertCallInstruction(const CallInst *Inst) { | 525 Ice::Inst *convertCallInstruction(const CallInst *Inst) { |
| 522 Ice::Variable *Dest = mapValueToIceVar(Inst); | 526 Ice::Variable *Dest = mapValueToIceVar(Inst); |
| 523 Ice::Operand *CallTarget = convertValue(Inst->getCalledValue()); | 527 Ice::Operand *CallTarget = convertValue(Inst->getCalledValue()); |
| 524 unsigned NumArgs = Inst->getNumArgOperands(); | 528 unsigned NumArgs = Inst->getNumArgOperands(); |
| 525 // Note: Subzero doesn't (yet) do anything special with the Tail | 529 // Note: Subzero doesn't (yet) do anything special with the Tail |
| 526 // flag in the bitcode, i.e. CallInst::isTailCall(). | 530 // flag in the bitcode, i.e. CallInst::isTailCall(). |
| 527 Ice::InstCall *NewInst = NULL; | 531 Ice::InstCall *NewInst = nullptr; |
| 528 const Ice::Intrinsics::FullIntrinsicInfo *Info = NULL; | 532 const Ice::Intrinsics::FullIntrinsicInfo *Info = nullptr; |
| 529 | 533 |
| 530 if (const auto Target = dyn_cast<Ice::ConstantRelocatable>(CallTarget)) { | 534 if (const auto Target = dyn_cast<Ice::ConstantRelocatable>(CallTarget)) { |
| 531 // Check if this direct call is to an Intrinsic (starts with "llvm.") | 535 // Check if this direct call is to an Intrinsic (starts with "llvm.") |
| 532 static const char LLVMPrefix[] = "llvm."; | 536 static const char LLVMPrefix[] = "llvm."; |
| 533 const size_t LLVMPrefixLen = strlen(LLVMPrefix); | 537 const size_t LLVMPrefixLen = strlen(LLVMPrefix); |
| 534 Ice::IceString Name = Target->getName(); | 538 Ice::IceString Name = Target->getName(); |
| 535 if (Name.substr(0, LLVMPrefixLen) == LLVMPrefix) { | 539 if (Name.substr(0, LLVMPrefixLen) == LLVMPrefix) { |
| 536 Ice::IceString NameSuffix = Name.substr(LLVMPrefixLen); | 540 Ice::IceString NameSuffix = Name.substr(LLVMPrefixLen); |
| 537 Info = Ctx->getIntrinsicsInfo().find(NameSuffix); | 541 Info = Ctx->getIntrinsicsInfo().find(NameSuffix); |
| 538 if (!Info) { | 542 if (!Info) { |
| 539 report_fatal_error(std::string("Invalid PNaCl intrinsic call: ") + | 543 report_fatal_error(std::string("Invalid PNaCl intrinsic call: ") + |
| 540 LLVMObjectAsString(Inst)); | 544 LLVMObjectAsString(Inst)); |
| 541 } | 545 } |
| 542 NewInst = Ice::InstIntrinsicCall::create(Func, NumArgs, Dest, | 546 NewInst = Ice::InstIntrinsicCall::create(Func, NumArgs, Dest, |
| 543 CallTarget, Info->Info); | 547 CallTarget, Info->Info); |
| 544 } | 548 } |
| 545 } | 549 } |
| 546 | 550 |
| 547 // Not an intrinsic call. | 551 // Not an intrinsic call. |
| 548 if (NewInst == NULL) { | 552 if (NewInst == nullptr) { |
| 549 NewInst = Ice::InstCall::create(Func, NumArgs, Dest, CallTarget, | 553 NewInst = Ice::InstCall::create(Func, NumArgs, Dest, CallTarget, |
| 550 Inst->isTailCall()); | 554 Inst->isTailCall()); |
| 551 } | 555 } |
| 552 for (unsigned i = 0; i < NumArgs; ++i) { | 556 for (unsigned i = 0; i < NumArgs; ++i) { |
| 553 NewInst->addArg(convertOperand(Inst, i)); | 557 NewInst->addArg(convertOperand(Inst, i)); |
| 554 } | 558 } |
| 555 if (Info) { | 559 if (Info) { |
| 556 validateIntrinsicCall(NewInst, Info); | 560 validateIntrinsicCall(NewInst, Info); |
| 557 } | 561 } |
| 558 return NewInst; | 562 return NewInst; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 629 // convertGlobalsToIce method. | 633 // convertGlobalsToIce method. |
| 630 // | 634 // |
| 631 // Note: this currently assumes that the given IR was verified to be | 635 // Note: this currently assumes that the given IR was verified to be |
| 632 // valid PNaCl bitcode. Othewise, the behavior is undefined. | 636 // valid PNaCl bitcode. Othewise, the behavior is undefined. |
| 633 class LLVM2ICEGlobalsConverter : public LLVM2ICEConverter { | 637 class LLVM2ICEGlobalsConverter : public LLVM2ICEConverter { |
| 634 LLVM2ICEGlobalsConverter(const LLVM2ICEGlobalsConverter &) = delete; | 638 LLVM2ICEGlobalsConverter(const LLVM2ICEGlobalsConverter &) = delete; |
| 635 LLVM2ICEGlobalsConverter & | 639 LLVM2ICEGlobalsConverter & |
| 636 operator-(const LLVM2ICEGlobalsConverter &) = delete; | 640 operator-(const LLVM2ICEGlobalsConverter &) = delete; |
| 637 | 641 |
| 638 public: | 642 public: |
| 639 LLVM2ICEGlobalsConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext) | 643 LLVM2ICEGlobalsConverter(Ice::Converter &Converter) |
| 640 : LLVM2ICEConverter(Ctx, LLVMContext) {} | 644 : LLVM2ICEConverter(Converter) {} |
| 641 | |
| 642 ~LLVM2ICEGlobalsConverter() { DeleteContainerSeconds(GlobalVarAddressMap); } | |
| 643 | 645 |
| 644 /// Converts global variables, and their initializers into ICE global | 646 /// Converts global variables, and their initializers into ICE global |
| 645 /// addresses, for module Mod. Puts corresponding converted global | 647 /// addresses, for module Mod. Puts corresponding converted global |
|
jvoung (off chromium)
2014/10/10 23:01:16
Sorry about the churn, but could convert the comme
Karl
2014/10/13 17:43:01
Done.
| |
| 646 /// addresses into GlobalAddresses. | 648 /// addresses into VariableDeclarations. |
| 647 void convertGlobalsToIce(Module *Mod, | 649 void convertGlobalsToIce( |
| 648 Ice::Translator::GlobalAddressList &GlobalAddresses); | 650 Module *Mod, |
| 651 Ice::Translator::VariableDeclarationListType &VariableDeclarations); | |
| 649 | 652 |
| 650 private: | 653 private: |
| 651 typedef std::map<const GlobalVariable *, Ice::GlobalAddress *> | |
| 652 GlobalVarAddressMapType; | |
| 653 // Map from global variables to their corresponding global address. | |
| 654 GlobalVarAddressMapType GlobalVarAddressMap; | |
| 655 | |
| 656 // Adds the Initializer to the list of initializers for Global address. | 654 // Adds the Initializer to the list of initializers for Global address. |
| 657 void addGlobalInitializer(Ice::GlobalAddress &Global, | 655 void addGlobalInitializer(Ice::VariableDeclaration &Global, |
| 658 const Constant *Initializer) { | 656 const Constant *Initializer) { |
| 659 const bool HasOffset = false; | 657 const bool HasOffset = false; |
| 660 const Ice::GlobalAddress::RelocOffsetType Offset = 0; | 658 const Ice::VariableDeclaration::RelocOffsetType Offset = 0; |
| 661 addGlobalInitializer(Global, Initializer, HasOffset, Offset); | 659 addGlobalInitializer(Global, Initializer, HasOffset, Offset); |
| 662 } | 660 } |
| 663 | 661 |
| 664 // Adds Initializer to the list of initializers for Global | 662 // Adds Initializer to the list of initializers for Global |
| 665 // address. HasOffset is true only if Initializer is a relocation | 663 // address. HasOffset is true only if Initializer is a relocation |
| 666 // initializer and Offset should be added to the relocation. | 664 // initializer and Offset should be added to the relocation. |
| 667 void addGlobalInitializer(Ice::GlobalAddress &Global, | 665 void addGlobalInitializer(Ice::VariableDeclaration &Global, |
| 668 const Constant *Initializer, bool HasOffset, | 666 const Constant *Initializer, bool HasOffset, |
| 669 Ice::GlobalAddress::RelocOffsetType Offset); | 667 Ice::VariableDeclaration::RelocOffsetType Offset); |
| 670 | |
| 671 // Returns the global address associated with global variable GV. | |
| 672 Ice::GlobalAddress *getGlobalVarAddress(const GlobalVariable *GV) { | |
| 673 if (GlobalVarAddressMap.find(GV) == GlobalVarAddressMap.end()) | |
| 674 GlobalVarAddressMap[GV] = new Ice::GlobalAddress(); | |
| 675 return GlobalVarAddressMap[GV]; | |
| 676 } | |
| 677 | 668 |
| 678 // Converts the given constant C to the corresponding integer | 669 // Converts the given constant C to the corresponding integer |
| 679 // literal it contains. | 670 // literal it contains. |
| 680 Ice::GlobalAddress::RelocOffsetType | 671 Ice::VariableDeclaration::RelocOffsetType |
| 681 getIntegerLiteralConstant(const Value *C) { | 672 getIntegerLiteralConstant(const Value *C) { |
| 682 const auto CI = dyn_cast<ConstantInt>(C); | 673 const auto CI = dyn_cast<ConstantInt>(C); |
| 683 if (CI && CI->getType()->isIntegerTy(32)) | 674 if (CI && CI->getType()->isIntegerTy(32)) |
| 684 return CI->getSExtValue(); | 675 return CI->getSExtValue(); |
| 685 | 676 |
| 686 std::string Buffer; | 677 std::string Buffer; |
| 687 raw_string_ostream StrBuf(Buffer); | 678 raw_string_ostream StrBuf(Buffer); |
| 688 StrBuf << "Constant not i32 literal: " << *C; | 679 StrBuf << "Constant not i32 literal: " << *C; |
| 689 report_fatal_error(StrBuf.str()); | 680 report_fatal_error(StrBuf.str()); |
| 690 return 0; | 681 return 0; |
| 691 } | 682 } |
| 692 }; | 683 }; |
| 693 | 684 |
| 694 void LLVM2ICEGlobalsConverter::convertGlobalsToIce( | 685 void LLVM2ICEGlobalsConverter::convertGlobalsToIce( |
| 695 Module *Mod, Ice::Translator::GlobalAddressList &GlobalAddresses) { | 686 Module *Mod, |
| 687 Ice::Translator::VariableDeclarationListType &VariableDeclarations) { | |
| 696 for (Module::const_global_iterator I = Mod->global_begin(), | 688 for (Module::const_global_iterator I = Mod->global_begin(), |
| 697 E = Mod->global_end(); | 689 E = Mod->global_end(); |
| 698 I != E; ++I) { | 690 I != E; ++I) { |
| 699 if (!I->hasInitializer() && Ctx->getFlags().AllowUninitializedGlobals) | 691 if (!I->hasInitializer() && Ctx->getFlags().AllowUninitializedGlobals) |
| 700 continue; | 692 continue; |
| 701 | 693 |
| 702 const auto GV = dyn_cast<GlobalVariable>(I); | 694 const GlobalVariable *GV = I; |
| 703 assert(GV); | |
| 704 Ice::IceString Name = GV->getName(); | 695 Ice::IceString Name = GV->getName(); |
| 705 if (!GV->hasInternalLinkage()) { | 696 if (!GV->hasInternalLinkage()) { |
| 706 std::string Buffer; | 697 std::string Buffer; |
| 707 raw_string_ostream StrBuf(Buffer); | 698 raw_string_ostream StrBuf(Buffer); |
| 708 StrBuf << "Can't define external global address: " << Name; | 699 StrBuf << "Can't define external global address: " << Name; |
| 709 report_fatal_error(StrBuf.str()); | 700 report_fatal_error(StrBuf.str()); |
| 710 } | 701 } |
| 711 | 702 |
| 712 Ice::GlobalAddress *Addr = getGlobalVarAddress(GV); | 703 Ice::GlobalDeclaration *Addr = getConverter().getGlobalDeclaration(GV); |
| 713 GlobalAddresses.push_back(Addr); | 704 auto VarAddr = cast<Ice::VariableDeclaration>(Addr); |
| 714 Addr->setAlignment(GV->getAlignment()); | 705 VariableDeclarations.push_back(VarAddr); |
| 715 Addr->setIsConstant(GV->isConstant()); | |
| 716 // Note: We allow external for cross tests. | |
| 717 Addr->setIsInternal(!GV->isExternallyInitialized()); | |
| 718 Addr->setName(Name); | |
| 719 | 706 |
| 720 const Constant *Initializer = GV->getInitializer(); | 707 const Constant *Initializer = GV->getInitializer(); |
| 721 if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) { | 708 if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) { |
| 722 for (ConstantStruct::const_op_iterator I = CompoundInit->op_begin(), | 709 for (ConstantStruct::const_op_iterator I = CompoundInit->op_begin(), |
| 723 E = CompoundInit->op_end(); | 710 E = CompoundInit->op_end(); |
| 724 I != E; ++I) { | 711 I != E; ++I) { |
| 725 if (const auto Init = dyn_cast<Constant>(I)) { | 712 if (const auto Init = dyn_cast<Constant>(I)) { |
| 726 addGlobalInitializer(*Addr, Init); | 713 addGlobalInitializer(*VarAddr, Init); |
| 727 } | 714 } |
| 728 } | 715 } |
| 729 } else { | 716 } else { |
| 730 addGlobalInitializer(*Addr, Initializer); | 717 addGlobalInitializer(*VarAddr, Initializer); |
| 731 } | 718 } |
| 732 } | 719 } |
| 733 } | 720 } |
| 734 | 721 |
| 735 void LLVM2ICEGlobalsConverter::addGlobalInitializer( | 722 void LLVM2ICEGlobalsConverter::addGlobalInitializer( |
| 736 Ice::GlobalAddress &Global, const Constant *Initializer, bool HasOffset, | 723 Ice::VariableDeclaration &Global, const Constant *Initializer, |
| 737 Ice::GlobalAddress::RelocOffsetType Offset) { | 724 bool HasOffset, Ice::VariableDeclaration::RelocOffsetType Offset) { |
| 738 assert(HasOffset || Offset == 0); | 725 assert(HasOffset || Offset == 0); |
| 739 | 726 |
| 740 if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) { | 727 if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) { |
| 741 assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) && | 728 assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) && |
| 742 (cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8)); | 729 (cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8)); |
| 743 Global.addInitializer(new Ice::GlobalAddress::DataInitializer( | 730 Global.addInitializer(new Ice::VariableDeclaration::DataInitializer( |
| 744 CDA->getRawDataValues().data(), CDA->getNumElements())); | 731 CDA->getRawDataValues().data(), CDA->getNumElements())); |
| 745 return; | 732 return; |
| 746 } | 733 } |
| 747 | 734 |
| 748 if (isa<ConstantAggregateZero>(Initializer)) { | 735 if (isa<ConstantAggregateZero>(Initializer)) { |
| 749 if (const auto AT = dyn_cast<ArrayType>(Initializer->getType())) { | 736 if (const auto AT = dyn_cast<ArrayType>(Initializer->getType())) { |
| 750 assert(!HasOffset && isa<IntegerType>(AT->getElementType()) && | 737 assert(!HasOffset && isa<IntegerType>(AT->getElementType()) && |
| 751 (cast<IntegerType>(AT->getElementType())->getBitWidth() == 8)); | 738 (cast<IntegerType>(AT->getElementType())->getBitWidth() == 8)); |
| 752 Global.addInitializer( | 739 Global.addInitializer( |
| 753 new Ice::GlobalAddress::ZeroInitializer(AT->getNumElements())); | 740 new Ice::VariableDeclaration::ZeroInitializer(AT->getNumElements())); |
| 754 } else { | 741 } else { |
| 755 llvm_unreachable("Unhandled constant aggregate zero type"); | 742 llvm_unreachable("Unhandled constant aggregate zero type"); |
| 756 } | 743 } |
| 757 return; | 744 return; |
| 758 } | 745 } |
| 759 | 746 |
| 760 if (const auto Exp = dyn_cast<ConstantExpr>(Initializer)) { | 747 if (const auto Exp = dyn_cast<ConstantExpr>(Initializer)) { |
| 761 switch (Exp->getOpcode()) { | 748 switch (Exp->getOpcode()) { |
| 762 case Instruction::Add: | 749 case Instruction::Add: |
| 763 assert(!HasOffset); | 750 assert(!HasOffset); |
| 764 addGlobalInitializer(Global, Exp->getOperand(0), true, | 751 addGlobalInitializer(Global, Exp->getOperand(0), true, |
| 765 getIntegerLiteralConstant(Exp->getOperand(1))); | 752 getIntegerLiteralConstant(Exp->getOperand(1))); |
| 766 return; | 753 return; |
| 767 case Instruction::PtrToInt: { | 754 case Instruction::PtrToInt: { |
| 768 assert(TypeConverter.convertToIceType(Exp->getType()) == | 755 assert(TypeConverter.convertToIceType(Exp->getType()) == |
| 769 TypeConverter.getIcePointerType()); | 756 TypeConverter.getIcePointerType()); |
| 770 const auto GV = dyn_cast<GlobalValue>(Exp->getOperand(0)); | 757 const auto GV = dyn_cast<GlobalValue>(Exp->getOperand(0)); |
| 771 assert(GV); | 758 assert(GV); |
| 772 if (const auto Fcn = dyn_cast<Function>(GV)) { | 759 const Ice::GlobalDeclaration *Addr = |
| 773 Ice::GlobalAddress::RelocationAddress Addr(Fcn); | 760 getConverter().getGlobalDeclaration(GV); |
| 774 Global.addInitializer( | 761 Global.addInitializer( |
| 775 new Ice::GlobalAddress::RelocInitializer(Addr, Offset)); | 762 new Ice::VariableDeclaration::RelocInitializer(Addr, Offset)); |
| 776 return; | 763 return; |
| 777 } else if (const auto Var = dyn_cast<GlobalVariable>(GV)) { | |
| 778 Ice::GlobalAddress::RelocationAddress Addr(getGlobalVarAddress(Var)); | |
| 779 Global.addInitializer( | |
| 780 new Ice::GlobalAddress::RelocInitializer(Addr, Offset)); | |
| 781 return; | |
| 782 } | |
| 783 break; | |
| 784 } | 764 } |
| 785 default: | 765 default: |
| 786 break; | 766 break; |
| 787 } | 767 } |
| 788 } | 768 } |
| 789 | 769 |
| 790 std::string Buffer; | 770 std::string Buffer; |
| 791 raw_string_ostream StrBuf(Buffer); | 771 raw_string_ostream StrBuf(Buffer); |
| 792 StrBuf << "Unhandled global initializer: " << Initializer; | 772 StrBuf << "Unhandled global initializer: " << Initializer; |
| 793 report_fatal_error(StrBuf.str()); | 773 report_fatal_error(StrBuf.str()); |
| 794 } | 774 } |
| 795 | 775 |
| 796 } // end of anonymous namespace | 776 } // end of anonymous namespace |
| 797 | 777 |
| 798 namespace Ice { | 778 namespace Ice { |
| 799 | 779 |
| 780 void Converter::nameUnnamedGlobalVariables(Module *Mod) { | |
| 781 const IceString &GlobalPrefix = Flags.DefaultGlobalPrefix; | |
| 782 if (GlobalPrefix.empty()) | |
| 783 return; | |
| 784 uint32_t NameIndex = 0; | |
| 785 Ostream &errs = Ctx->getStrDump(); | |
| 786 for (auto V = Mod->global_begin(), E = Mod->global_end(); V != E; ++V) { | |
| 787 if (!V->hasName()) { | |
| 788 V->setName(createUnnamedName(GlobalPrefix, NameIndex)); | |
| 789 ++NameIndex; | |
| 790 } else { | |
| 791 checkIfUnnamedNameSafe(V->getName(), "global", GlobalPrefix, errs); | |
| 792 } | |
| 793 } | |
| 794 } | |
| 795 | |
| 796 void Converter::nameUnnamedFunctions(Module *Mod) { | |
| 797 const IceString &FunctionPrefix = Flags.DefaultFunctionPrefix; | |
| 798 if (FunctionPrefix.empty()) | |
| 799 return; | |
| 800 uint32_t NameIndex = 0; | |
| 801 Ostream &errs = Ctx->getStrDump(); | |
| 802 for (Function &F : *Mod) { | |
| 803 if (!F.hasName()) { | |
| 804 F.setName(createUnnamedName(FunctionPrefix, NameIndex)); | |
| 805 ++NameIndex; | |
| 806 } else { | |
| 807 checkIfUnnamedNameSafe(F.getName(), "function", FunctionPrefix, errs); | |
| 808 } | |
| 809 } | |
| 810 } | |
| 811 | |
| 800 void Converter::convertToIce() { | 812 void Converter::convertToIce() { |
| 801 TimerMarker T(TimerStack::TT_convertToIce, Ctx); | 813 TimerMarker T(TimerStack::TT_convertToIce, Ctx); |
| 802 nameUnnamedGlobalAddresses(Mod); | 814 nameUnnamedGlobalVariables(Mod); |
| 803 nameUnnamedFunctions(Mod); | 815 nameUnnamedFunctions(Mod); |
| 816 installGlobalDeclarations(Mod); | |
| 804 convertGlobals(Mod); | 817 convertGlobals(Mod); |
| 805 convertFunctions(); | 818 convertFunctions(); |
| 806 } | 819 } |
| 807 | 820 |
| 821 GlobalDeclaration *Converter::getGlobalDeclaration(const GlobalValue *V) { | |
| 822 GlobalDeclarationMapType::const_iterator Pos = GlobalDeclarationMap.find(V); | |
| 823 if (Pos == GlobalDeclarationMap.end()) { | |
| 824 std::string Buffer; | |
| 825 raw_string_ostream StrBuf(Buffer); | |
| 826 StrBuf << "Can't find global address for: " << V->getName(); | |
| 827 report_fatal_error(StrBuf.str()); | |
| 828 } | |
| 829 return Pos->second; | |
| 830 } | |
| 831 | |
| 832 void Converter::installGlobalDeclarations(Module *Mod) { | |
| 833 const TypeConverter Converter(Mod->getContext()); | |
| 834 // Install function addresses. | |
|
jvoung (off chromium)
2014/10/10 23:01:16
addresses -> declarations
Karl
2014/10/13 17:43:02
Done.
| |
| 835 for (const Function &Func : *Mod) { | |
| 836 FuncSigType Signature; | |
| 837 FunctionType *FuncType = Func.getFunctionType(); | |
| 838 Signature.setReturnType( | |
| 839 Converter.convertToIceType(FuncType->getReturnType())); | |
| 840 for (size_t I = 0; I < FuncType->getNumParams(); ++I) { | |
| 841 Signature.appendArgType( | |
| 842 Converter.convertToIceType(FuncType->getParamType(I))); | |
| 843 } | |
| 844 FunctionDeclaration *IceFunc = FunctionDeclaration::create( | |
| 845 Ctx, Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty()); | |
| 846 IceFunc->setName(Func.getName()); | |
| 847 GlobalDeclarationMap[&Func] = IceFunc; | |
| 848 } | |
| 849 // Install global variable addresses. | |
| 850 for (Module::const_global_iterator I = Mod->global_begin(), | |
| 851 E = Mod->global_end(); | |
| 852 I != E; ++I) { | |
| 853 const GlobalVariable *GV = I; | |
| 854 VariableDeclaration *Var = VariableDeclaration::create(Ctx); | |
| 855 Var->setName(GV->getName()); | |
| 856 Var->setAlignment(GV->getAlignment()); | |
| 857 Var->setIsConstant(GV->isConstant()); | |
| 858 // Note: We allow external for cross tests. | |
| 859 // TODO(kschimpf) Put behind flag AllowUninitializedGlobals. | |
| 860 Var->setIsInternal(!GV->isExternallyInitialized()); | |
| 861 GlobalDeclarationMap[GV] = Var; | |
| 862 } | |
| 863 } | |
| 864 | |
| 808 void Converter::convertGlobals(Module *Mod) { | 865 void Converter::convertGlobals(Module *Mod) { |
| 809 LLVM2ICEGlobalsConverter GlobalsConverter(Ctx, Mod->getContext()); | 866 LLVM2ICEGlobalsConverter GlobalsConverter(*this); |
| 810 Translator::GlobalAddressList GlobalAddresses; | 867 Translator::VariableDeclarationListType VariableDeclarations; |
| 811 GlobalsConverter.convertGlobalsToIce(Mod, GlobalAddresses); | 868 GlobalsConverter.convertGlobalsToIce(Mod, VariableDeclarations); |
| 812 lowerGlobals(GlobalAddresses); | 869 lowerGlobals(VariableDeclarations); |
| 813 } | 870 } |
| 814 | 871 |
| 815 void Converter::convertFunctions() { | 872 void Converter::convertFunctions() { |
| 816 TimerStackIdT StackID = GlobalContext::TSK_Funcs; | 873 TimerStackIdT StackID = GlobalContext::TSK_Funcs; |
| 817 for (const Function &I : *Mod) { | 874 for (const Function &I : *Mod) { |
| 818 if (I.empty()) | 875 if (I.empty()) |
| 819 continue; | 876 continue; |
| 820 | 877 |
| 821 TimerIdT TimerID = 0; | 878 TimerIdT TimerID = 0; |
| 822 if (Ctx->getFlags().TimeEachFunction) { | 879 if (Ctx->getFlags().TimeEachFunction) { |
| 823 TimerID = Ctx->getTimerID(StackID, I.getName()); | 880 TimerID = Ctx->getTimerID(StackID, I.getName()); |
| 824 Ctx->pushTimer(TimerID, StackID); | 881 Ctx->pushTimer(TimerID, StackID); |
| 825 } | 882 } |
| 826 LLVM2ICEFunctionConverter FunctionConverter(Ctx, Mod->getContext()); | 883 LLVM2ICEFunctionConverter FunctionConverter(*this); |
| 827 | 884 |
| 828 Cfg *Fcn = FunctionConverter.convertFunction(&I); | 885 Cfg *Fcn = FunctionConverter.convertFunction(&I); |
| 829 translateFcn(Fcn); | 886 translateFcn(Fcn); |
| 830 if (Ctx->getFlags().TimeEachFunction) | 887 if (Ctx->getFlags().TimeEachFunction) |
| 831 Ctx->popTimer(TimerID, StackID); | 888 Ctx->popTimer(TimerID, StackID); |
| 832 } | 889 } |
| 833 | 890 |
| 834 emitConstants(); | 891 emitConstants(); |
| 835 } | 892 } |
| 836 | 893 |
| 837 } // end of namespace Ice | 894 } // end of namespace Ice |
| OLD | NEW |