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

Unified Diff: src/IceConverter.cpp

Issue 624663002: Introduce model of global initializers in Subzero. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. 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 side-by-side diff with in-line comments
Download patch
Index: src/IceConverter.cpp
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp
index 9d59c56980f072b8215de1b0acda4dfcfafce45e..ed9f13aabd87e7ceea8c2ebcf05bc99bd42117e1 100644
--- a/src/IceConverter.cpp
+++ b/src/IceConverter.cpp
@@ -27,6 +27,7 @@
#include "IceConverter.h"
#include "IceDefs.h"
#include "IceGlobalContext.h"
+#include "IceGlobalInits.h"
#include "IceInst.h"
#include "IceOperand.h"
#include "IceTargetLowering.h"
@@ -45,17 +46,29 @@ template <typename T> static std::string LLVMObjectAsString(const T *O) {
return Stream.str();
}
-// Converter from LLVM to ICE. The entry point is the convertFunction method.
+// Base class for converting LLVM to ICE.
+class LLVM2ICEConverter {
+public:
+ LLVM2ICEConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext)
+ : Ctx(Ctx), TypeConverter(LLVMContext) {}
+
+protected:
+ // Data
+ Ice::GlobalContext *Ctx;
+ Ice::TypeConverter TypeConverter;
jvoung (off chromium) 2014/10/03 16:15:29 Could disallow copy / assign.
Karl 2014/10/04 16:28:33 Done.
+};
+
+// Converter from LLVM functions to ICE. The entry point is the
+// convertFunction method.
//
-// Note: this currently assumes that the given IR was verified to be valid PNaCl
-// bitcode:
+// Note: this currently assumes that the given IR was verified to be
+// valid PNaCl bitcode:
// https://developers.google.com/native-client/dev/reference/pnacl-bitcode-abi
// If not, all kinds of assertions may fire.
-//
-class LLVM2ICEConverter {
+class LLVM2ICEFunctionConverter : LLVM2ICEConverter {
public:
- LLVM2ICEConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext)
- : Ctx(Ctx), Func(NULL), TypeConverter(LLVMContext) {}
+ LLVM2ICEFunctionConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext)
+ : LLVM2ICEConverter(Ctx, LLVMContext), Func(NULL) {}
// Caller is expected to delete the returned Ice::Cfg object.
Ice::Cfg *convertFunction(const Function *F) {
@@ -611,13 +624,185 @@ private:
private:
// Data
- Ice::GlobalContext *Ctx;
Ice::Cfg *Func;
std::map<const Value *, Ice::Variable *> VarMap;
std::map<const BasicBlock *, Ice::CfgNode *> NodeMap;
- Ice::TypeConverter TypeConverter;
};
+// Converter from LLVM global variables to ICE. The entry point is the
+// convertGlobalsToIce method.
+//
+// Note: this currently assumes that the given IR was verified to be
+// valid PNaCl bitcode:
+// https://developers.google.com/native-client/dev/reference/pnacl-bitcode-abi
+// If not, all kinds of assertions may fire.
+class LLVM2ICEGlobalsConverter : public LLVM2ICEConverter {
+public:
+ LLVM2ICEGlobalsConverter(Ice::GlobalContext *Ctx, LLVMContext &LLVMContext)
+ : LLVM2ICEConverter(Ctx, LLVMContext) {}
+
+ ~LLVM2ICEGlobalsConverter() {
+ llvm::DeleteContainerSeconds(GlobalVarAddressMap);
+ }
+
+ /// Converts global variables, and their initializers into ICE global
+ /// addresses, for module Mod. Puts corresponding converted global
+ /// addresses into GlobalAddresses.
+ void convertGlobalsToIce(llvm::Module *Mod,
+ std::vector<Ice::GlobalAddress *> &GlobalAddresses);
Jim Stichnoth 2014/10/03 01:28:08 Can you make a typedef for std::vector<Ice::Global
Karl 2014/10/04 16:28:33 Added typedef Translator::GlobalAddressList. Adde
+
+private:
+ // Map from global variables to thier corresponding global address.
Jim Stichnoth 2014/10/03 01:28:08 their
Karl 2014/10/04 16:28:33 Done.
+ std::map<const llvm::GlobalVariable *, Ice::GlobalAddress *>
+ GlobalVarAddressMap;
+
+ // Adds the Initializer to the list of initializers for Global address.
+ void AddGlobalInitializer(Ice::GlobalAddress &Global,
jvoung (off chromium) 2014/10/03 16:15:29 method name consistency: "addGlobalInitializer" in
Karl 2014/10/04 16:28:33 Done.
+ const llvm::Constant *Initializer) {
+ AddGlobalInitializer(Global, Initializer, false, 0);
jvoung (off chromium) 2014/10/03 16:15:29 nit: For some of the other code in Subzero, there
Karl 2014/10/04 16:28:33 Done.
+ }
+
+ // 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,
+ const llvm::Constant *Initializer, bool HasOffset,
+ Ice::GlobalAddress::RelocOffsetType Offset);
+
+ // Returns the global address associated with global variable GV.
+ Ice::GlobalAddress *getGlobalVarAddress(const llvm::GlobalVariable *GV) {
+ Ice::GlobalAddress *Addr = GlobalVarAddressMap[GV];
Jim Stichnoth 2014/10/03 01:28:08 Maybe better form to do something like this? if
Karl 2014/10/04 16:28:33 Done.
+ if (Addr)
+ return Addr;
+ Addr = new Ice::GlobalAddress();
+ GlobalVarAddressMap[GV] = Addr;
+ return Addr;
+ }
+
+ // Converts the given constant C to the corresponding integer
+ // literal it contains.
+ Ice::GlobalAddress::RelocOffsetType
+ getIntegerLiteralConstant(const llvm::Value *C) {
+ const llvm::ConstantInt *CI = llvm::dyn_cast<llvm::ConstantInt>(C);
Jim Stichnoth 2014/10/03 01:28:08 if (auto CI = llvm::dyn_cast<const llvm::ConstantI
Karl 2014/10/04 16:28:33 Fixed all occurrences in file.
+ if (CI && CI->getType()->isIntegerTy(32))
+ return CI->getSExtValue();
+
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Constant not i32 literal: " << *C;
+ report_fatal_error(StrBuf.str());
+ return 0;
+ }
+};
+
+void LLVM2ICEGlobalsConverter::convertGlobalsToIce(
+ llvm::Module *Mod, std::vector<Ice::GlobalAddress *> &GlobalAddresses) {
+ for (llvm::Module::const_global_iterator I = Mod->global_begin(),
+ E = Mod->global_end();
+ I != E; ++I) {
+ if (!I->hasInitializer())
+ continue;
jvoung (off chromium) 2014/10/03 16:15:29 For the PNaCl ABI, should we be stricter? I though
Karl 2014/10/04 16:28:33 I agree. I was being lazy because there is a test
+
+ const llvm::GlobalVariable *GV = llvm::dyn_cast<GlobalVariable>(I);
+ assert(GV);
Jim Stichnoth 2014/10/03 01:28:08 If you're going to assert(GV), might as well use l
Karl 2014/10/04 16:28:33 Not sure what you are asking. Are you asking to pu
+ Ice::IceString Name = GV->getName();
+ if (!GV->hasInternalLinkage()) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Can't define external global address: " << Name;
+ report_fatal_error(StrBuf.str());
+ }
+
+ Ice::GlobalAddress *Addr = getGlobalVarAddress(GV);
+ GlobalAddresses.push_back(Addr);
+ Addr->setAlignment(GV->getAlignment());
+ Addr->setIsConstant(GV->isConstant());
+ Addr->setName(Name);
+
+ const llvm::Constant *Initializer = GV->getInitializer();
+ if (const llvm::ConstantStruct *CompoundInit =
+ dyn_cast<llvm::ConstantStruct>(Initializer)) {
+ for (llvm::ConstantStruct::const_op_iterator i = CompoundInit->op_begin(),
Jim Stichnoth 2014/10/03 01:28:08 Use I and E instead of i and e for consistency?
Karl 2014/10/04 16:28:33 Done.
+ e = CompoundInit->op_end();
+ i != e; ++i) {
+ if (const llvm::Constant *Init = dyn_cast<llvm::Constant>(i)) {
+ AddGlobalInitializer(*Addr, Init);
+ }
jvoung (off chromium) 2014/10/03 16:15:29 What are the possible "else" here, and should it b
Karl 2014/10/04 16:28:33 The format in PNaCl ABI is that the struct is part
+ }
+ } else {
+ AddGlobalInitializer(*Addr, Initializer);
+ }
+ }
+}
+
+void LLVM2ICEGlobalsConverter::AddGlobalInitializer(
+ Ice::GlobalAddress &Global, const llvm::Constant *Initializer,
+ bool HasOffset, Ice::GlobalAddress::RelocOffsetType Offset) {
+ assert(HasOffset || Offset == 0);
+
+ if (const llvm::ConstantDataArray *CDA =
+ llvm::dyn_cast<llvm::ConstantDataArray>(Initializer)) {
+ assert(!HasOffset && llvm::isa<llvm::IntegerType>(CDA->getElementType()) &&
+ (llvm::cast<llvm::IntegerType>(CDA->getElementType())
+ ->getBitWidth() == 8));
+ Global.AddInitializer(new Ice::GlobalAddress::DataInitializer(
+ CDA->getRawDataValues().data(), CDA->getNumElements()));
+ return;
+ }
+
+ if (llvm::isa<llvm::ConstantAggregateZero>(Initializer)) {
+ if (const llvm::ArrayType *AT =
+ llvm::dyn_cast<llvm::ArrayType>(Initializer->getType())) {
+ assert(!HasOffset && llvm::isa<llvm::IntegerType>(AT->getElementType()) &&
+ (llvm::cast<llvm::IntegerType>(AT->getElementType())
+ ->getBitWidth() == 8));
+ Global.AddInitializer(
+ new Ice::GlobalAddress::ZeroInitializer(AT->getNumElements()));
+ } else {
+ llvm_unreachable("Unhandled constant aggregate zero type");
+ }
+ return;
+ }
+
+ if (const ConstantExpr *Exp =
+ llvm::dyn_cast<llvm::ConstantExpr>(Initializer)) {
+ switch (Exp->getOpcode()) {
+ case Instruction::Add:
+ assert(!HasOffset);
+ AddGlobalInitializer(Global, Exp->getOperand(0), true,
+ getIntegerLiteralConstant(Exp->getOperand(1)));
+ return;
+ case Instruction::PtrToInt: {
+ assert(TypeConverter.convertToIceType(Exp->getType()) ==
+ TypeConverter.getIcePointerType());
+ llvm::GlobalValue *GV =
+ llvm::dyn_cast<llvm::GlobalValue>(Exp->getOperand(0));
+ assert(GV);
+ if (llvm::Function *Fcn = llvm::dyn_cast<Function>(GV)) {
+ Ice::GlobalAddress::RelocationAddress Addr(Fcn);
+ Global.AddInitializer(
+ new Ice::GlobalAddress::RelocInitializer(Addr, Offset));
+ return;
+ } else if (llvm::GlobalVariable *Var =
+ llvm::dyn_cast<llvm::GlobalVariable>(GV)) {
+ Ice::GlobalAddress::RelocationAddress Addr(getGlobalVarAddress(Var));
+ Global.AddInitializer(
+ new Ice::GlobalAddress::RelocInitializer(Addr, Offset));
+ return;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Unhandled global initializer: " << Initializer;
+ report_fatal_error(StrBuf.str());
+}
+
} // end of anonymous namespace
namespace Ice {
@@ -626,16 +811,24 @@ void Converter::convertToIce() {
static TimerIdT IDconvertToIce = GlobalContext::getTimerID("convertToIce");
TimerMarker T(IDconvertToIce, Ctx);
nameUnnamedGlobalAddresses(Mod);
+ nameUnnamedFunctions(Mod);
if (!Ctx->getFlags().DisableGlobals)
convertGlobals(Mod);
convertFunctions();
}
+void Converter::convertGlobals(llvm::Module *Mod) {
+ LLVM2ICEGlobalsConverter GlobalsConverter(Ctx, Mod->getContext());
+ std::vector<Ice::GlobalAddress *> GlobalAddresses;
+ GlobalsConverter.convertGlobalsToIce(Mod, GlobalAddresses);
+ lowerIceGlobals(GlobalAddresses);
+}
+
void Converter::convertFunctions() {
for (Module::const_iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) {
if (I->empty())
continue;
- LLVM2ICEConverter FunctionConverter(Ctx, Mod->getContext());
+ LLVM2ICEFunctionConverter FunctionConverter(Ctx, Mod->getContext());
Timer TConvert;
Cfg *Fcn = FunctionConverter.convertFunction(I);
« no previous file with comments | « src/IceConverter.h ('k') | src/IceGlobalInits.h » ('j') | src/IceGlobalInits.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698