Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: src/IceConverter.cpp

Issue 641193002: Introduce the notion of function addresses in Subzero. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nit in test. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceConverter.h ('k') | src/IceDefs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceConverter.h ('k') | src/IceDefs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698