| 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 | 645 |
| 642 ~LLVM2ICEGlobalsConverter() { DeleteContainerSeconds(GlobalVarAddressMap); } | 646 /// Converts global variables, and their initializers into ICE |
| 643 | 647 /// global variable declarations, for module Mod. Puts corresponding |
| 644 /// Converts global variables, and their initializers into ICE global | 648 /// converted declarations into VariableDeclarations. |
| 645 /// addresses, for module Mod. Puts corresponding converted global | 649 void convertGlobalsToIce( |
| 646 /// addresses into GlobalAddresses. | 650 Module *Mod, |
| 647 void convertGlobalsToIce(Module *Mod, | 651 Ice::Translator::VariableDeclarationListType &VariableDeclarations); |
| 648 Ice::Translator::GlobalAddressList &GlobalAddresses); | |
| 649 | 652 |
| 650 private: | 653 private: |
| 651 typedef std::map<const GlobalVariable *, Ice::GlobalAddress *> | 654 // Adds the Initializer to the list of initializers for the Global |
| 652 GlobalVarAddressMapType; | 655 // variable declaraation. |
| 653 // Map from global variables to their corresponding global address. | 656 void addGlobalInitializer(Ice::VariableDeclaration &Global, |
| 654 GlobalVarAddressMapType GlobalVarAddressMap; | |
| 655 | |
| 656 // Adds the Initializer to the list of initializers for Global address. | |
| 657 void addGlobalInitializer(Ice::GlobalAddress &Global, | |
| 658 const Constant *Initializer) { | 657 const Constant *Initializer) { |
| 659 const bool HasOffset = false; | 658 const bool HasOffset = false; |
| 660 const Ice::GlobalAddress::RelocOffsetType Offset = 0; | 659 const Ice::VariableDeclaration::RelocOffsetType Offset = 0; |
| 661 addGlobalInitializer(Global, Initializer, HasOffset, Offset); | 660 addGlobalInitializer(Global, Initializer, HasOffset, Offset); |
| 662 } | 661 } |
| 663 | 662 |
| 664 // Adds Initializer to the list of initializers for Global | 663 // Adds Initializer to the list of initializers for Global variable |
| 665 // address. HasOffset is true only if Initializer is a relocation | 664 // declaration. HasOffset is true only if Initializer is a |
| 666 // initializer and Offset should be added to the relocation. | 665 // relocation initializer and Offset should be added to the |
| 667 void addGlobalInitializer(Ice::GlobalAddress &Global, | 666 // relocation. |
| 667 void addGlobalInitializer(Ice::VariableDeclaration &Global, |
| 668 const Constant *Initializer, bool HasOffset, | 668 const Constant *Initializer, bool HasOffset, |
| 669 Ice::GlobalAddress::RelocOffsetType Offset); | 669 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 | 670 |
| 678 // Converts the given constant C to the corresponding integer | 671 // Converts the given constant C to the corresponding integer |
| 679 // literal it contains. | 672 // literal it contains. |
| 680 Ice::GlobalAddress::RelocOffsetType | 673 Ice::VariableDeclaration::RelocOffsetType |
| 681 getIntegerLiteralConstant(const Value *C) { | 674 getIntegerLiteralConstant(const Value *C) { |
| 682 const auto CI = dyn_cast<ConstantInt>(C); | 675 const auto CI = dyn_cast<ConstantInt>(C); |
| 683 if (CI && CI->getType()->isIntegerTy(32)) | 676 if (CI && CI->getType()->isIntegerTy(32)) |
| 684 return CI->getSExtValue(); | 677 return CI->getSExtValue(); |
| 685 | 678 |
| 686 std::string Buffer; | 679 std::string Buffer; |
| 687 raw_string_ostream StrBuf(Buffer); | 680 raw_string_ostream StrBuf(Buffer); |
| 688 StrBuf << "Constant not i32 literal: " << *C; | 681 StrBuf << "Constant not i32 literal: " << *C; |
| 689 report_fatal_error(StrBuf.str()); | 682 report_fatal_error(StrBuf.str()); |
| 690 return 0; | 683 return 0; |
| 691 } | 684 } |
| 692 }; | 685 }; |
| 693 | 686 |
| 694 void LLVM2ICEGlobalsConverter::convertGlobalsToIce( | 687 void LLVM2ICEGlobalsConverter::convertGlobalsToIce( |
| 695 Module *Mod, Ice::Translator::GlobalAddressList &GlobalAddresses) { | 688 Module *Mod, |
| 689 Ice::Translator::VariableDeclarationListType &VariableDeclarations) { |
| 696 for (Module::const_global_iterator I = Mod->global_begin(), | 690 for (Module::const_global_iterator I = Mod->global_begin(), |
| 697 E = Mod->global_end(); | 691 E = Mod->global_end(); |
| 698 I != E; ++I) { | 692 I != E; ++I) { |
| 699 if (!I->hasInitializer() && Ctx->getFlags().AllowUninitializedGlobals) | 693 if (!I->hasInitializer() && Ctx->getFlags().AllowUninitializedGlobals) |
| 700 continue; | 694 continue; |
| 701 | 695 |
| 702 const auto GV = dyn_cast<GlobalVariable>(I); | 696 const GlobalVariable *GV = I; |
| 703 assert(GV); | |
| 704 Ice::IceString Name = GV->getName(); | 697 Ice::IceString Name = GV->getName(); |
| 705 if (!GV->hasInternalLinkage()) { | 698 if (!GV->hasInternalLinkage()) { |
| 706 std::string Buffer; | 699 std::string Buffer; |
| 707 raw_string_ostream StrBuf(Buffer); | 700 raw_string_ostream StrBuf(Buffer); |
| 708 StrBuf << "Can't define external global address: " << Name; | 701 StrBuf << "Can't define external global declaration: " << Name; |
| 709 report_fatal_error(StrBuf.str()); | 702 report_fatal_error(StrBuf.str()); |
| 710 } | 703 } |
| 711 | 704 |
| 712 Ice::GlobalAddress *Addr = getGlobalVarAddress(GV); | 705 Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV); |
| 713 GlobalAddresses.push_back(Addr); | 706 Ice::VariableDeclaration* VarDecl = cast<Ice::VariableDeclaration>(Var); |
| 714 Addr->setAlignment(GV->getAlignment()); | 707 VariableDeclarations.push_back(VarDecl); |
| 715 Addr->setIsConstant(GV->isConstant()); | |
| 716 // Note: We allow external for cross tests. | |
| 717 Addr->setIsInternal(!GV->isExternallyInitialized()); | |
| 718 Addr->setName(Name); | |
| 719 | 708 |
| 720 const Constant *Initializer = GV->getInitializer(); | 709 const Constant *Initializer = GV->getInitializer(); |
| 721 if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) { | 710 if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) { |
| 722 for (ConstantStruct::const_op_iterator I = CompoundInit->op_begin(), | 711 for (ConstantStruct::const_op_iterator I = CompoundInit->op_begin(), |
| 723 E = CompoundInit->op_end(); | 712 E = CompoundInit->op_end(); |
| 724 I != E; ++I) { | 713 I != E; ++I) { |
| 725 if (const auto Init = dyn_cast<Constant>(I)) { | 714 if (const auto Init = dyn_cast<Constant>(I)) { |
| 726 addGlobalInitializer(*Addr, Init); | 715 addGlobalInitializer(*VarDecl, Init); |
| 727 } | 716 } |
| 728 } | 717 } |
| 729 } else { | 718 } else { |
| 730 addGlobalInitializer(*Addr, Initializer); | 719 addGlobalInitializer(*VarDecl, Initializer); |
| 731 } | 720 } |
| 732 } | 721 } |
| 733 } | 722 } |
| 734 | 723 |
| 735 void LLVM2ICEGlobalsConverter::addGlobalInitializer( | 724 void LLVM2ICEGlobalsConverter::addGlobalInitializer( |
| 736 Ice::GlobalAddress &Global, const Constant *Initializer, bool HasOffset, | 725 Ice::VariableDeclaration &Global, const Constant *Initializer, |
| 737 Ice::GlobalAddress::RelocOffsetType Offset) { | 726 bool HasOffset, Ice::VariableDeclaration::RelocOffsetType Offset) { |
| 727 (void)HasOffset; |
| 738 assert(HasOffset || Offset == 0); | 728 assert(HasOffset || Offset == 0); |
| 739 | 729 |
| 740 if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) { | 730 if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) { |
| 741 assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) && | 731 assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) && |
| 742 (cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8)); | 732 (cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8)); |
| 743 Global.addInitializer(new Ice::GlobalAddress::DataInitializer( | 733 Global.addInitializer(new Ice::VariableDeclaration::DataInitializer( |
| 744 CDA->getRawDataValues().data(), CDA->getNumElements())); | 734 CDA->getRawDataValues().data(), CDA->getNumElements())); |
| 745 return; | 735 return; |
| 746 } | 736 } |
| 747 | 737 |
| 748 if (isa<ConstantAggregateZero>(Initializer)) { | 738 if (isa<ConstantAggregateZero>(Initializer)) { |
| 749 if (const auto AT = dyn_cast<ArrayType>(Initializer->getType())) { | 739 if (const auto AT = dyn_cast<ArrayType>(Initializer->getType())) { |
| 750 assert(!HasOffset && isa<IntegerType>(AT->getElementType()) && | 740 assert(!HasOffset && isa<IntegerType>(AT->getElementType()) && |
| 751 (cast<IntegerType>(AT->getElementType())->getBitWidth() == 8)); | 741 (cast<IntegerType>(AT->getElementType())->getBitWidth() == 8)); |
| 752 Global.addInitializer( | 742 Global.addInitializer( |
| 753 new Ice::GlobalAddress::ZeroInitializer(AT->getNumElements())); | 743 new Ice::VariableDeclaration::ZeroInitializer(AT->getNumElements())); |
| 754 } else { | 744 } else { |
| 755 llvm_unreachable("Unhandled constant aggregate zero type"); | 745 llvm_unreachable("Unhandled constant aggregate zero type"); |
| 756 } | 746 } |
| 757 return; | 747 return; |
| 758 } | 748 } |
| 759 | 749 |
| 760 if (const auto Exp = dyn_cast<ConstantExpr>(Initializer)) { | 750 if (const auto Exp = dyn_cast<ConstantExpr>(Initializer)) { |
| 761 switch (Exp->getOpcode()) { | 751 switch (Exp->getOpcode()) { |
| 762 case Instruction::Add: | 752 case Instruction::Add: |
| 763 assert(!HasOffset); | 753 assert(!HasOffset); |
| 764 addGlobalInitializer(Global, Exp->getOperand(0), true, | 754 addGlobalInitializer(Global, Exp->getOperand(0), true, |
| 765 getIntegerLiteralConstant(Exp->getOperand(1))); | 755 getIntegerLiteralConstant(Exp->getOperand(1))); |
| 766 return; | 756 return; |
| 767 case Instruction::PtrToInt: { | 757 case Instruction::PtrToInt: { |
| 768 assert(TypeConverter.convertToIceType(Exp->getType()) == | 758 assert(TypeConverter.convertToIceType(Exp->getType()) == |
| 769 TypeConverter.getIcePointerType()); | 759 TypeConverter.getIcePointerType()); |
| 770 const auto GV = dyn_cast<GlobalValue>(Exp->getOperand(0)); | 760 const auto GV = dyn_cast<GlobalValue>(Exp->getOperand(0)); |
| 771 assert(GV); | 761 assert(GV); |
| 772 if (const auto Fcn = dyn_cast<Function>(GV)) { | 762 const Ice::GlobalDeclaration *Addr = |
| 773 Ice::GlobalAddress::RelocationAddress Addr(Fcn); | 763 getConverter().getGlobalDeclaration(GV); |
| 774 Global.addInitializer( | 764 Global.addInitializer( |
| 775 new Ice::GlobalAddress::RelocInitializer(Addr, Offset)); | 765 new Ice::VariableDeclaration::RelocInitializer(Addr, Offset)); |
| 776 return; | 766 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 } | 767 } |
| 785 default: | 768 default: |
| 786 break; | 769 break; |
| 787 } | 770 } |
| 788 } | 771 } |
| 789 | 772 |
| 790 std::string Buffer; | 773 std::string Buffer; |
| 791 raw_string_ostream StrBuf(Buffer); | 774 raw_string_ostream StrBuf(Buffer); |
| 792 StrBuf << "Unhandled global initializer: " << Initializer; | 775 StrBuf << "Unhandled global initializer: " << Initializer; |
| 793 report_fatal_error(StrBuf.str()); | 776 report_fatal_error(StrBuf.str()); |
| 794 } | 777 } |
| 795 | 778 |
| 796 } // end of anonymous namespace | 779 } // end of anonymous namespace |
| 797 | 780 |
| 798 namespace Ice { | 781 namespace Ice { |
| 799 | 782 |
| 783 void Converter::nameUnnamedGlobalVariables(Module *Mod) { |
| 784 const IceString &GlobalPrefix = Flags.DefaultGlobalPrefix; |
| 785 if (GlobalPrefix.empty()) |
| 786 return; |
| 787 uint32_t NameIndex = 0; |
| 788 Ostream &errs = Ctx->getStrDump(); |
| 789 for (auto V = Mod->global_begin(), E = Mod->global_end(); V != E; ++V) { |
| 790 if (!V->hasName()) { |
| 791 V->setName(createUnnamedName(GlobalPrefix, NameIndex)); |
| 792 ++NameIndex; |
| 793 } else { |
| 794 checkIfUnnamedNameSafe(V->getName(), "global", GlobalPrefix, errs); |
| 795 } |
| 796 } |
| 797 } |
| 798 |
| 799 void Converter::nameUnnamedFunctions(Module *Mod) { |
| 800 const IceString &FunctionPrefix = Flags.DefaultFunctionPrefix; |
| 801 if (FunctionPrefix.empty()) |
| 802 return; |
| 803 uint32_t NameIndex = 0; |
| 804 Ostream &errs = Ctx->getStrDump(); |
| 805 for (Function &F : *Mod) { |
| 806 if (!F.hasName()) { |
| 807 F.setName(createUnnamedName(FunctionPrefix, NameIndex)); |
| 808 ++NameIndex; |
| 809 } else { |
| 810 checkIfUnnamedNameSafe(F.getName(), "function", FunctionPrefix, errs); |
| 811 } |
| 812 } |
| 813 } |
| 814 |
| 800 void Converter::convertToIce() { | 815 void Converter::convertToIce() { |
| 801 TimerMarker T(TimerStack::TT_convertToIce, Ctx); | 816 TimerMarker T(TimerStack::TT_convertToIce, Ctx); |
| 802 nameUnnamedGlobalAddresses(Mod); | 817 nameUnnamedGlobalVariables(Mod); |
| 803 nameUnnamedFunctions(Mod); | 818 nameUnnamedFunctions(Mod); |
| 819 installGlobalDeclarations(Mod); |
| 804 convertGlobals(Mod); | 820 convertGlobals(Mod); |
| 805 convertFunctions(); | 821 convertFunctions(); |
| 806 } | 822 } |
| 807 | 823 |
| 824 GlobalDeclaration *Converter::getGlobalDeclaration(const GlobalValue *V) { |
| 825 GlobalDeclarationMapType::const_iterator Pos = GlobalDeclarationMap.find(V); |
| 826 if (Pos == GlobalDeclarationMap.end()) { |
| 827 std::string Buffer; |
| 828 raw_string_ostream StrBuf(Buffer); |
| 829 StrBuf << "Can't find global declaration for: " << V->getName(); |
| 830 report_fatal_error(StrBuf.str()); |
| 831 } |
| 832 return Pos->second; |
| 833 } |
| 834 |
| 835 void Converter::installGlobalDeclarations(Module *Mod) { |
| 836 const TypeConverter Converter(Mod->getContext()); |
| 837 // Install function declarations. |
| 838 for (const Function &Func : *Mod) { |
| 839 FuncSigType Signature; |
| 840 FunctionType *FuncType = Func.getFunctionType(); |
| 841 Signature.setReturnType( |
| 842 Converter.convertToIceType(FuncType->getReturnType())); |
| 843 for (size_t I = 0; I < FuncType->getNumParams(); ++I) { |
| 844 Signature.appendArgType( |
| 845 Converter.convertToIceType(FuncType->getParamType(I))); |
| 846 } |
| 847 FunctionDeclaration *IceFunc = FunctionDeclaration::create( |
| 848 Ctx, Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty()); |
| 849 IceFunc->setName(Func.getName()); |
| 850 GlobalDeclarationMap[&Func] = IceFunc; |
| 851 } |
| 852 // Install global variable declarations. |
| 853 for (Module::const_global_iterator I = Mod->global_begin(), |
| 854 E = Mod->global_end(); |
| 855 I != E; ++I) { |
| 856 const GlobalVariable *GV = I; |
| 857 VariableDeclaration *Var = VariableDeclaration::create(Ctx); |
| 858 Var->setName(GV->getName()); |
| 859 Var->setAlignment(GV->getAlignment()); |
| 860 Var->setIsConstant(GV->isConstant()); |
| 861 // Note: We allow external for cross tests. |
| 862 // TODO(kschimpf) Put behind flag AllowUninitializedGlobals. |
| 863 Var->setIsInternal(!GV->isExternallyInitialized()); |
| 864 GlobalDeclarationMap[GV] = Var; |
| 865 } |
| 866 } |
| 867 |
| 808 void Converter::convertGlobals(Module *Mod) { | 868 void Converter::convertGlobals(Module *Mod) { |
| 809 LLVM2ICEGlobalsConverter GlobalsConverter(Ctx, Mod->getContext()); | 869 LLVM2ICEGlobalsConverter GlobalsConverter(*this); |
| 810 Translator::GlobalAddressList GlobalAddresses; | 870 Translator::VariableDeclarationListType VariableDeclarations; |
| 811 GlobalsConverter.convertGlobalsToIce(Mod, GlobalAddresses); | 871 GlobalsConverter.convertGlobalsToIce(Mod, VariableDeclarations); |
| 812 lowerGlobals(GlobalAddresses); | 872 lowerGlobals(VariableDeclarations); |
| 813 } | 873 } |
| 814 | 874 |
| 815 void Converter::convertFunctions() { | 875 void Converter::convertFunctions() { |
| 816 TimerStackIdT StackID = GlobalContext::TSK_Funcs; | 876 TimerStackIdT StackID = GlobalContext::TSK_Funcs; |
| 817 for (const Function &I : *Mod) { | 877 for (const Function &I : *Mod) { |
| 818 if (I.empty()) | 878 if (I.empty()) |
| 819 continue; | 879 continue; |
| 820 | 880 |
| 821 TimerIdT TimerID = 0; | 881 TimerIdT TimerID = 0; |
| 822 if (Ctx->getFlags().TimeEachFunction) { | 882 if (Ctx->getFlags().TimeEachFunction) { |
| 823 TimerID = Ctx->getTimerID(StackID, I.getName()); | 883 TimerID = Ctx->getTimerID(StackID, I.getName()); |
| 824 Ctx->pushTimer(TimerID, StackID); | 884 Ctx->pushTimer(TimerID, StackID); |
| 825 } | 885 } |
| 826 LLVM2ICEFunctionConverter FunctionConverter(Ctx, Mod->getContext()); | 886 LLVM2ICEFunctionConverter FunctionConverter(*this); |
| 827 | 887 |
| 828 Cfg *Fcn = FunctionConverter.convertFunction(&I); | 888 Cfg *Fcn = FunctionConverter.convertFunction(&I); |
| 829 translateFcn(Fcn); | 889 translateFcn(Fcn); |
| 830 if (Ctx->getFlags().TimeEachFunction) | 890 if (Ctx->getFlags().TimeEachFunction) |
| 831 Ctx->popTimer(TimerID, StackID); | 891 Ctx->popTimer(TimerID, StackID); |
| 832 } | 892 } |
| 833 | 893 |
| 834 emitConstants(); | 894 emitConstants(); |
| 835 } | 895 } |
| 836 | 896 |
| 837 } // end of namespace Ice | 897 } // end of namespace Ice |
| OLD | NEW |