Index: src/IceConverter.cpp |
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp |
index 380f1a0dd88be21afc73e5fea42567ac72af24d9..a97cb6857008a75aa5d8cca93d3fe58256c80eff 100644 |
--- a/src/IceConverter.cpp |
+++ b/src/IceConverter.cpp |
@@ -34,6 +34,7 @@ |
#include "IceTypes.h" |
#include "IceTypeConverter.h" |
+// TODO(kschimpf): Remove two namespaces being visible at once. |
using namespace llvm; |
namespace { |
@@ -52,11 +53,14 @@ class LLVM2ICEConverter { |
LLVM2ICEConverter &operator=(const LLVM2ICEConverter &) = delete; |
public: |
- LLVM2ICEConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext) |
- : Ctx(Ctx), TypeConverter(LLVMContext) {} |
+ LLVM2ICEConverter(Ice::Converter &Converter) |
+ : Converter(Converter), Ctx(Converter.getContext()), |
+ TypeConverter(Converter.getModule()->getContext()) {} |
+ |
+ Ice::Converter &getConverter() const { return Converter; } |
protected: |
- // Data |
+ Ice::Converter &Converter; |
Ice::GlobalContext *Ctx; |
const Ice::TypeConverter TypeConverter; |
}; |
@@ -72,8 +76,8 @@ class LLVM2ICEFunctionConverter : LLVM2ICEConverter { |
operator=(const LLVM2ICEFunctionConverter &) = delete; |
public: |
- LLVM2ICEFunctionConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext) |
- : LLVM2ICEConverter(Ctx, LLVMContext), Func(NULL) {} |
+ LLVM2ICEFunctionConverter(Ice::Converter &Converter) |
+ : LLVM2ICEConverter(Converter), Func(nullptr) {} |
// Caller is expected to delete the returned Ice::Cfg object. |
Ice::Cfg *convertFunction(const Function *F) { |
@@ -126,12 +130,12 @@ public: |
else if (Type == Ice::IceType_f64) |
return Ctx->getConstantDouble(CFP->getValueAPF().convertToDouble()); |
llvm_unreachable("Unexpected floating point type"); |
- return NULL; |
+ return nullptr; |
} else if (const auto CU = dyn_cast<UndefValue>(Const)) { |
return Ctx->getConstantUndef(convertToIceType(CU->getType())); |
} else { |
llvm_unreachable("Unhandled constant type"); |
- return NULL; |
+ return nullptr; |
} |
} |
@@ -141,7 +145,7 @@ private: |
// and a version that just uses convertToIceType on V. |
Ice::Variable *mapValueToIceVar(const Value *V, Ice::Type IceTy) { |
if (IceTy == Ice::IceType_void) |
- return NULL; |
+ return nullptr; |
if (VarMap.find(V) == VarMap.end()) { |
VarMap[V] = Func->makeVariable(IceTy, V->getName()); |
} |
@@ -169,10 +173,10 @@ private: |
// Given an LLVM instruction and an operand number, produce the |
// Ice::Operand this refers to. If there's no such operand, return |
- // NULL. |
+ // nullptr. |
Ice::Operand *convertOperand(const Instruction *Inst, unsigned OpNum) { |
if (OpNum >= Inst->getNumOperands()) { |
- return NULL; |
+ return nullptr; |
} |
const Value *Op = Inst->getOperand(OpNum); |
return convertValue(Op); |
@@ -292,7 +296,7 @@ private: |
} |
llvm_unreachable("convertInstruction"); |
- return NULL; |
+ return nullptr; |
} |
Ice::Inst *convertLoadInstruction(const LoadInst *Inst) { |
@@ -524,8 +528,8 @@ private: |
unsigned NumArgs = Inst->getNumArgOperands(); |
// Note: Subzero doesn't (yet) do anything special with the Tail |
// flag in the bitcode, i.e. CallInst::isTailCall(). |
- Ice::InstCall *NewInst = NULL; |
- const Ice::Intrinsics::FullIntrinsicInfo *Info = NULL; |
+ Ice::InstCall *NewInst = nullptr; |
+ const Ice::Intrinsics::FullIntrinsicInfo *Info = nullptr; |
if (const auto Target = dyn_cast<Ice::ConstantRelocatable>(CallTarget)) { |
// Check if this direct call is to an Intrinsic (starts with "llvm.") |
@@ -545,7 +549,7 @@ private: |
} |
// Not an intrinsic call. |
- if (NewInst == NULL) { |
+ if (NewInst == nullptr) { |
NewInst = Ice::InstCall::create(Func, NumArgs, Dest, CallTarget, |
Inst->isTailCall()); |
} |
@@ -636,48 +640,37 @@ class LLVM2ICEGlobalsConverter : public LLVM2ICEConverter { |
operator-(const LLVM2ICEGlobalsConverter &) = delete; |
public: |
- LLVM2ICEGlobalsConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext) |
- : LLVM2ICEConverter(Ctx, LLVMContext) {} |
- |
- ~LLVM2ICEGlobalsConverter() { DeleteContainerSeconds(GlobalVarAddressMap); } |
+ LLVM2ICEGlobalsConverter(Ice::Converter &Converter) |
+ : LLVM2ICEConverter(Converter) {} |
- /// Converts global variables, and their initializers into ICE global |
- /// addresses, for module Mod. Puts corresponding converted global |
- /// addresses into GlobalAddresses. |
- void convertGlobalsToIce(Module *Mod, |
- Ice::Translator::GlobalAddressList &GlobalAddresses); |
+ /// Converts global variables, and their initializers into ICE |
+ /// global variable declarations, for module Mod. Puts corresponding |
+ /// converted declarations into VariableDeclarations. |
+ void convertGlobalsToIce( |
+ Module *Mod, |
+ Ice::Translator::VariableDeclarationListType &VariableDeclarations); |
private: |
- typedef std::map<const GlobalVariable *, Ice::GlobalAddress *> |
- GlobalVarAddressMapType; |
- // Map from global variables to their corresponding global address. |
- GlobalVarAddressMapType GlobalVarAddressMap; |
- |
- // Adds the Initializer to the list of initializers for Global address. |
- void addGlobalInitializer(Ice::GlobalAddress &Global, |
+ // Adds the Initializer to the list of initializers for the Global |
+ // variable declaraation. |
+ void addGlobalInitializer(Ice::VariableDeclaration &Global, |
const Constant *Initializer) { |
const bool HasOffset = false; |
- const Ice::GlobalAddress::RelocOffsetType Offset = 0; |
+ const Ice::VariableDeclaration::RelocOffsetType Offset = 0; |
addGlobalInitializer(Global, Initializer, HasOffset, Offset); |
} |
- // Adds Initializer to the list of initializers for Global |
- // address. HasOffset is true only if Initializer is a relocation |
- // initializer and Offset should be added to the relocation. |
- void addGlobalInitializer(Ice::GlobalAddress &Global, |
+ // Adds Initializer to the list of initializers for Global variable |
+ // declaration. HasOffset is true only if Initializer is a |
+ // relocation initializer and Offset should be added to the |
+ // relocation. |
+ void addGlobalInitializer(Ice::VariableDeclaration &Global, |
const Constant *Initializer, bool HasOffset, |
- Ice::GlobalAddress::RelocOffsetType Offset); |
- |
- // Returns the global address associated with global variable GV. |
- Ice::GlobalAddress *getGlobalVarAddress(const GlobalVariable *GV) { |
- if (GlobalVarAddressMap.find(GV) == GlobalVarAddressMap.end()) |
- GlobalVarAddressMap[GV] = new Ice::GlobalAddress(); |
- return GlobalVarAddressMap[GV]; |
- } |
+ Ice::VariableDeclaration::RelocOffsetType Offset); |
// Converts the given constant C to the corresponding integer |
// literal it contains. |
- Ice::GlobalAddress::RelocOffsetType |
+ Ice::VariableDeclaration::RelocOffsetType |
getIntegerLiteralConstant(const Value *C) { |
const auto CI = dyn_cast<ConstantInt>(C); |
if (CI && CI->getType()->isIntegerTy(32)) |
@@ -692,30 +685,26 @@ private: |
}; |
void LLVM2ICEGlobalsConverter::convertGlobalsToIce( |
- Module *Mod, Ice::Translator::GlobalAddressList &GlobalAddresses) { |
+ Module *Mod, |
+ Ice::Translator::VariableDeclarationListType &VariableDeclarations) { |
for (Module::const_global_iterator I = Mod->global_begin(), |
E = Mod->global_end(); |
I != E; ++I) { |
if (!I->hasInitializer() && Ctx->getFlags().AllowUninitializedGlobals) |
continue; |
- const auto GV = dyn_cast<GlobalVariable>(I); |
- assert(GV); |
+ const GlobalVariable *GV = I; |
Ice::IceString Name = GV->getName(); |
if (!GV->hasInternalLinkage()) { |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
- StrBuf << "Can't define external global address: " << Name; |
+ StrBuf << "Can't define external global declaration: " << Name; |
report_fatal_error(StrBuf.str()); |
} |
- Ice::GlobalAddress *Addr = getGlobalVarAddress(GV); |
- GlobalAddresses.push_back(Addr); |
- Addr->setAlignment(GV->getAlignment()); |
- Addr->setIsConstant(GV->isConstant()); |
- // Note: We allow external for cross tests. |
- Addr->setIsInternal(!GV->isExternallyInitialized()); |
- Addr->setName(Name); |
+ Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV); |
+ Ice::VariableDeclaration* VarDecl = cast<Ice::VariableDeclaration>(Var); |
+ VariableDeclarations.push_back(VarDecl); |
const Constant *Initializer = GV->getInitializer(); |
if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) { |
@@ -723,24 +712,25 @@ void LLVM2ICEGlobalsConverter::convertGlobalsToIce( |
E = CompoundInit->op_end(); |
I != E; ++I) { |
if (const auto Init = dyn_cast<Constant>(I)) { |
- addGlobalInitializer(*Addr, Init); |
+ addGlobalInitializer(*VarDecl, Init); |
} |
} |
} else { |
- addGlobalInitializer(*Addr, Initializer); |
+ addGlobalInitializer(*VarDecl, Initializer); |
} |
} |
} |
void LLVM2ICEGlobalsConverter::addGlobalInitializer( |
- Ice::GlobalAddress &Global, const Constant *Initializer, bool HasOffset, |
- Ice::GlobalAddress::RelocOffsetType Offset) { |
+ Ice::VariableDeclaration &Global, const Constant *Initializer, |
+ bool HasOffset, Ice::VariableDeclaration::RelocOffsetType Offset) { |
+ (void)HasOffset; |
assert(HasOffset || Offset == 0); |
if (const auto CDA = dyn_cast<ConstantDataArray>(Initializer)) { |
assert(!HasOffset && isa<IntegerType>(CDA->getElementType()) && |
(cast<IntegerType>(CDA->getElementType())->getBitWidth() == 8)); |
- Global.addInitializer(new Ice::GlobalAddress::DataInitializer( |
+ Global.addInitializer(new Ice::VariableDeclaration::DataInitializer( |
CDA->getRawDataValues().data(), CDA->getNumElements())); |
return; |
} |
@@ -750,7 +740,7 @@ void LLVM2ICEGlobalsConverter::addGlobalInitializer( |
assert(!HasOffset && isa<IntegerType>(AT->getElementType()) && |
(cast<IntegerType>(AT->getElementType())->getBitWidth() == 8)); |
Global.addInitializer( |
- new Ice::GlobalAddress::ZeroInitializer(AT->getNumElements())); |
+ new Ice::VariableDeclaration::ZeroInitializer(AT->getNumElements())); |
} else { |
llvm_unreachable("Unhandled constant aggregate zero type"); |
} |
@@ -769,18 +759,11 @@ void LLVM2ICEGlobalsConverter::addGlobalInitializer( |
TypeConverter.getIcePointerType()); |
const auto GV = dyn_cast<GlobalValue>(Exp->getOperand(0)); |
assert(GV); |
- if (const auto Fcn = dyn_cast<Function>(GV)) { |
- Ice::GlobalAddress::RelocationAddress Addr(Fcn); |
- Global.addInitializer( |
- new Ice::GlobalAddress::RelocInitializer(Addr, Offset)); |
- return; |
- } else if (const auto Var = dyn_cast<GlobalVariable>(GV)) { |
- Ice::GlobalAddress::RelocationAddress Addr(getGlobalVarAddress(Var)); |
- Global.addInitializer( |
- new Ice::GlobalAddress::RelocInitializer(Addr, Offset)); |
- return; |
- } |
- break; |
+ const Ice::GlobalDeclaration *Addr = |
+ getConverter().getGlobalDeclaration(GV); |
+ Global.addInitializer( |
+ new Ice::VariableDeclaration::RelocInitializer(Addr, Offset)); |
+ return; |
} |
default: |
break; |
@@ -797,19 +780,96 @@ void LLVM2ICEGlobalsConverter::addGlobalInitializer( |
namespace Ice { |
+void Converter::nameUnnamedGlobalVariables(Module *Mod) { |
+ const IceString &GlobalPrefix = Flags.DefaultGlobalPrefix; |
+ if (GlobalPrefix.empty()) |
+ return; |
+ uint32_t NameIndex = 0; |
+ Ostream &errs = Ctx->getStrDump(); |
+ for (auto V = Mod->global_begin(), E = Mod->global_end(); V != E; ++V) { |
+ if (!V->hasName()) { |
+ V->setName(createUnnamedName(GlobalPrefix, NameIndex)); |
+ ++NameIndex; |
+ } else { |
+ checkIfUnnamedNameSafe(V->getName(), "global", GlobalPrefix, errs); |
+ } |
+ } |
+} |
+ |
+void Converter::nameUnnamedFunctions(Module *Mod) { |
+ const IceString &FunctionPrefix = Flags.DefaultFunctionPrefix; |
+ if (FunctionPrefix.empty()) |
+ return; |
+ uint32_t NameIndex = 0; |
+ Ostream &errs = Ctx->getStrDump(); |
+ for (Function &F : *Mod) { |
+ if (!F.hasName()) { |
+ F.setName(createUnnamedName(FunctionPrefix, NameIndex)); |
+ ++NameIndex; |
+ } else { |
+ checkIfUnnamedNameSafe(F.getName(), "function", FunctionPrefix, errs); |
+ } |
+ } |
+} |
+ |
void Converter::convertToIce() { |
TimerMarker T(TimerStack::TT_convertToIce, Ctx); |
- nameUnnamedGlobalAddresses(Mod); |
+ nameUnnamedGlobalVariables(Mod); |
nameUnnamedFunctions(Mod); |
+ installGlobalDeclarations(Mod); |
convertGlobals(Mod); |
convertFunctions(); |
} |
+GlobalDeclaration *Converter::getGlobalDeclaration(const GlobalValue *V) { |
+ GlobalDeclarationMapType::const_iterator Pos = GlobalDeclarationMap.find(V); |
+ if (Pos == GlobalDeclarationMap.end()) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Can't find global declaration for: " << V->getName(); |
+ report_fatal_error(StrBuf.str()); |
+ } |
+ return Pos->second; |
+} |
+ |
+void Converter::installGlobalDeclarations(Module *Mod) { |
+ const TypeConverter Converter(Mod->getContext()); |
+ // Install function declarations. |
+ for (const Function &Func : *Mod) { |
+ FuncSigType Signature; |
+ FunctionType *FuncType = Func.getFunctionType(); |
+ Signature.setReturnType( |
+ Converter.convertToIceType(FuncType->getReturnType())); |
+ for (size_t I = 0; I < FuncType->getNumParams(); ++I) { |
+ Signature.appendArgType( |
+ Converter.convertToIceType(FuncType->getParamType(I))); |
+ } |
+ FunctionDeclaration *IceFunc = FunctionDeclaration::create( |
+ Ctx, Signature, Func.getCallingConv(), Func.getLinkage(), Func.empty()); |
+ IceFunc->setName(Func.getName()); |
+ GlobalDeclarationMap[&Func] = IceFunc; |
+ } |
+ // Install global variable declarations. |
+ for (Module::const_global_iterator I = Mod->global_begin(), |
+ E = Mod->global_end(); |
+ I != E; ++I) { |
+ const GlobalVariable *GV = I; |
+ VariableDeclaration *Var = VariableDeclaration::create(Ctx); |
+ Var->setName(GV->getName()); |
+ Var->setAlignment(GV->getAlignment()); |
+ Var->setIsConstant(GV->isConstant()); |
+ // Note: We allow external for cross tests. |
+ // TODO(kschimpf) Put behind flag AllowUninitializedGlobals. |
+ Var->setIsInternal(!GV->isExternallyInitialized()); |
+ GlobalDeclarationMap[GV] = Var; |
+ } |
+} |
+ |
void Converter::convertGlobals(Module *Mod) { |
- LLVM2ICEGlobalsConverter GlobalsConverter(Ctx, Mod->getContext()); |
- Translator::GlobalAddressList GlobalAddresses; |
- GlobalsConverter.convertGlobalsToIce(Mod, GlobalAddresses); |
- lowerGlobals(GlobalAddresses); |
+ LLVM2ICEGlobalsConverter GlobalsConverter(*this); |
+ Translator::VariableDeclarationListType VariableDeclarations; |
+ GlobalsConverter.convertGlobalsToIce(Mod, VariableDeclarations); |
+ lowerGlobals(VariableDeclarations); |
} |
void Converter::convertFunctions() { |
@@ -823,7 +883,7 @@ void Converter::convertFunctions() { |
TimerID = Ctx->getTimerID(StackID, I.getName()); |
Ctx->pushTimer(TimerID, StackID); |
} |
- LLVM2ICEFunctionConverter FunctionConverter(Ctx, Mod->getContext()); |
+ LLVM2ICEFunctionConverter FunctionConverter(*this); |
Cfg *Fcn = FunctionConverter.convertFunction(&I); |
translateFcn(Fcn); |