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 |