Commit 5ee234a7 by Karl Schimpf

Allow ability to name unnamed global addresses in Subzero.

This is a workaround for issue that Subzero currently assumes all global addresses have a name, but finalized pexe files leave most global addresses unnamed. It does this by allowing two optional command-line flag name prefixes that are used to generate names for unnamed global addresses. BUG= None R=stichnot@chromium.org Review URL: https://codereview.chromium.org/567703003
parent 44d53e1e
...@@ -14,20 +14,26 @@ ...@@ -14,20 +14,26 @@
#ifndef SUBZERO_SRC_ICECLFLAGS_H #ifndef SUBZERO_SRC_ICECLFLAGS_H
#define SUBZERO_SRC_ICECLFLAGS_H #define SUBZERO_SRC_ICECLFLAGS_H
#include "IceTypes.def"
namespace Ice { namespace Ice {
// TODO(stichnot) Move more command line flags into ClFlags.
class ClFlags { class ClFlags {
public: public:
ClFlags() ClFlags()
: DisableInternal(false), SubzeroTimingEnabled(false), : DisableInternal(false), SubzeroTimingEnabled(false),
DisableTranslation(false), DisableGlobals(false), DisableTranslation(false), DisableGlobals(false),
FunctionSections(false), UseSandboxing(false) {} FunctionSections(false), UseSandboxing(false), DefaultGlobalPrefix(""),
DefaultFunctionPrefix("") {}
bool DisableInternal; bool DisableInternal;
bool SubzeroTimingEnabled; bool SubzeroTimingEnabled;
bool DisableTranslation; bool DisableTranslation;
bool DisableGlobals; bool DisableGlobals;
bool FunctionSections; bool FunctionSections;
bool UseSandboxing; bool UseSandboxing;
IceString DefaultGlobalPrefix;
IceString DefaultFunctionPrefix;
}; };
} // end of namespace Ice } // end of namespace Ice
......
...@@ -608,6 +608,7 @@ private: ...@@ -608,6 +608,7 @@ private:
namespace Ice { namespace Ice {
void Converter::convertToIce() { void Converter::convertToIce() {
nameUnnamedGlobalAddresses(Mod);
if (!Ctx->getFlags().DisableGlobals) if (!Ctx->getFlags().DisableGlobals)
convertGlobals(); convertGlobals();
convertFunctions(); convertFunctions();
......
...@@ -16,7 +16,9 @@ ...@@ -16,7 +16,9 @@
#include "IceCfg.h" #include "IceCfg.h"
#include "IceClFlags.h" #include "IceClFlags.h"
#include "IceDefs.h"
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
#include "llvm/IR/Module.h"
#include <iostream> #include <iostream>
...@@ -24,14 +26,58 @@ using namespace Ice; ...@@ -24,14 +26,58 @@ using namespace Ice;
Translator::~Translator() {} Translator::~Translator() {}
void Translator::translateFcn(Ice::Cfg *Fcn) { namespace {
void setValueName(llvm::Value *V, const char *Kind, const IceString &Prefix,
uint32_t &NameIndex, Ostream &errs) {
if (V->hasName()) {
const std::string &Name(V->getName());
if (Name.find(Prefix) == 0) {
errs << "Warning: Default " << Kind << " prefix '" << Prefix
<< "' conflicts with name '" << Name << "'.\n";
}
return;
}
if (NameIndex == 0) {
V->setName(Prefix);
++NameIndex;
return;
}
std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer);
StrBuf << Prefix << NameIndex;
V->setName(StrBuf.str());
++NameIndex;
}
} // end of anonymous namespace
void Translator::nameUnnamedGlobalAddresses(llvm::Module *Mod) {
const IceString &GlobalPrefix = Flags.DefaultGlobalPrefix;
Ostream &errs = Ctx->getStrDump();
if (!GlobalPrefix.empty()) {
uint32_t NameIndex = 0;
for (llvm::Module::global_iterator I = Mod->global_begin(),
E = Mod->global_end();
I != E; ++I) {
setValueName(I, "global", GlobalPrefix, NameIndex, errs);
}
}
const IceString &FunctionPrefix = Flags.DefaultFunctionPrefix;
if (FunctionPrefix.empty())
return;
uint32_t NameIndex = 0;
for (llvm::Module::iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) {
setValueName(I, "function", FunctionPrefix, NameIndex, errs);
}
}
void Translator::translateFcn(Cfg *Fcn) {
Func.reset(Fcn); Func.reset(Fcn);
if (Ctx->getFlags().DisableInternal) if (Ctx->getFlags().DisableInternal)
Func->setInternal(false); Func->setInternal(false);
if (Ctx->getFlags().DisableTranslation) { if (Ctx->getFlags().DisableTranslation) {
Func->dump(); Func->dump();
} else { } else {
Ice::Timer TTranslate; Timer TTranslate;
Func->translate(); Func->translate();
if (Ctx->getFlags().SubzeroTimingEnabled) { if (Ctx->getFlags().SubzeroTimingEnabled) {
std::cerr << "[Subzero timing] Translate function " std::cerr << "[Subzero timing] Translate function "
...@@ -43,7 +89,7 @@ void Translator::translateFcn(Ice::Cfg *Fcn) { ...@@ -43,7 +89,7 @@ void Translator::translateFcn(Ice::Cfg *Fcn) {
ErrorStatus = true; ErrorStatus = true;
} }
Ice::Timer TEmit; Timer TEmit;
Func->emit(); Func->emit();
if (Ctx->getFlags().SubzeroTimingEnabled) { if (Ctx->getFlags().SubzeroTimingEnabled) {
std::cerr << "[Subzero timing] Emit function " << Func->getFunctionName() std::cerr << "[Subzero timing] Emit function " << Func->getFunctionName()
......
...@@ -17,6 +17,10 @@ ...@@ -17,6 +17,10 @@
#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/OwningPtr.h"
namespace llvm {
class Module;
}
namespace Ice { namespace Ice {
class ClFlags; class ClFlags;
...@@ -47,6 +51,11 @@ public: ...@@ -47,6 +51,11 @@ public:
/// Emits the constant pool. /// Emits the constant pool.
void emitConstants(); void emitConstants();
// Walks module and generates names for unnamed globals and
// functions using prefix getFlags().DefaultGlobalPrefix, if the
// prefix is non-empty.
void nameUnnamedGlobalAddresses(llvm::Module *Mod);
protected: protected:
GlobalContext *Ctx; GlobalContext *Ctx;
const ClFlags &Flags; const ClFlags &Flags;
......
...@@ -1887,11 +1887,14 @@ bool FunctionParser::ParseBlock(unsigned BlockID) { ...@@ -1887,11 +1887,14 @@ bool FunctionParser::ParseBlock(unsigned BlockID) {
class ModuleParser : public BlockParserBaseClass { class ModuleParser : public BlockParserBaseClass {
public: public:
ModuleParser(unsigned BlockID, TopLevelParser *Context) ModuleParser(unsigned BlockID, TopLevelParser *Context)
: BlockParserBaseClass(BlockID, Context) {} : BlockParserBaseClass(BlockID, Context), FoundFirstFunctionBlock(false) {
}
virtual ~ModuleParser() LLVM_OVERRIDE {} virtual ~ModuleParser() LLVM_OVERRIDE {}
protected: private:
// True if we have parsed a function block.
bool FoundFirstFunctionBlock;
virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE; virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
virtual void ProcessRecord() LLVM_OVERRIDE; virtual void ProcessRecord() LLVM_OVERRIDE;
...@@ -1950,6 +1953,10 @@ bool ModuleParser::ParseBlock(unsigned BlockID) LLVM_OVERRIDE { ...@@ -1950,6 +1953,10 @@ bool ModuleParser::ParseBlock(unsigned BlockID) LLVM_OVERRIDE {
return Parser.ParseThisBlock(); return Parser.ParseThisBlock();
} }
case naclbitc::FUNCTION_BLOCK_ID: { case naclbitc::FUNCTION_BLOCK_ID: {
if (!FoundFirstFunctionBlock) {
getTranslator().nameUnnamedGlobalAddresses(Context->getModule());
FoundFirstFunctionBlock = true;
}
FunctionParser Parser(BlockID, this); FunctionParser Parser(BlockID, this);
return Parser.ParseThisBlock(); return Parser.ParseThisBlock();
} }
......
...@@ -109,6 +109,18 @@ static cl::opt<NaClFileFormat> InputFileFormat( ...@@ -109,6 +109,18 @@ static cl::opt<NaClFileFormat> InputFileFormat(
clEnumValEnd), clEnumValEnd),
cl::init(LLVMFormat)); cl::init(LLVMFormat));
static cl::opt<std::string>
DefaultGlobalPrefix("default-global-prefix",
cl::desc("Define default global prefix for naming "
"unnamed globals"),
cl::init("Global"));
static cl::opt<std::string>
DefaultFunctionPrefix("default-function-prefix",
cl::desc("Define default function prefix for naming "
"unnamed functions"),
cl::init("Function"));
static cl::opt<bool> static cl::opt<bool>
BuildOnRead("build-on-read", BuildOnRead("build-on-read",
cl::desc("Build ICE instructions when reading bitcode"), cl::desc("Build ICE instructions when reading bitcode"),
...@@ -143,6 +155,8 @@ int main(int argc, char **argv) { ...@@ -143,6 +155,8 @@ int main(int argc, char **argv) {
Flags.DisableGlobals = DisableGlobals; Flags.DisableGlobals = DisableGlobals;
Flags.FunctionSections = FunctionSections; Flags.FunctionSections = FunctionSections;
Flags.UseSandboxing = UseSandboxing; Flags.UseSandboxing = UseSandboxing;
Flags.DefaultGlobalPrefix = DefaultGlobalPrefix;
Flags.DefaultFunctionPrefix = DefaultFunctionPrefix;
Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix, Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix,
Flags); Flags);
......
; Tests that we name unnamed global addresses.
; RUN: %llvm2ice -notranslate -verbose=inst < %s | FileCheck %s
; RUN: %llvm2ice -notranslate -verbose=inst -default-function-prefix=h \
; RUN: -default-global-prefix=g < %s | FileCheck --check-prefix=BAD %s
@0 = internal global [4 x i8] zeroinitializer, align 4
; CHECK: @Global = internal global [4 x i8] zeroinitializer, align 4
@1 = internal constant [10 x i8] c"Some stuff", align 1
; CHECK-NEXT: @Global1 = internal constant [10 x i8] c"Some stuff", align 1
@g = internal global [4 x i8] zeroinitializer, align 4
; BAD: Warning: Default global prefix 'g' conflicts with name 'g'.
; CHECK-NEXT: @g = internal global [4 x i8] zeroinitializer, align 4
define i32 @2(i32 %v) {
ret i32 %v
}
; CHECK-NEXT: define i32 @Function(i32 %v) {
; CHECK-NEXT: __0:
; CHECK-NEXT: ret i32 %v
; CHECK-NEXT: }
define void @hg() {
ret void
}
; BAD: Warning: Default function prefix 'h' conflicts with name 'hg'.
; CHECK-NEXT: define void @hg() {
; CHECK-NEXT: __0:
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @3() {
ret void
}
; CHECK-NEXT: define void @Function1() {
; CHECK-NEXT: __0:
; CHECK-NEXT: ret void
; CHECK-NEXT: }
; Tests that we name unnamed global addresses.
; RUN: llvm-as < %s | pnacl-freeze \
; RUN: | %llvm2ice -notranslate -verbose=inst -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery \
; RUN: | FileCheck %s
; RUN: llvm-as < %s | pnacl-freeze \
; RUN: | %llvm2ice -notranslate -verbose=inst -build-on-read \
; RUN: -default-function-prefix=h -default-global-prefix=g \
; RUN: -allow-pnacl-reader-error-recovery \
; RUN: | FileCheck --check-prefix=BAD %s
; TODO(kschimpf) Check global variable declarations, once generated.
@0 = internal global [4 x i8] zeroinitializer, align 4
@1 = internal constant [10 x i8] c"Some stuff", align 1
@g = internal global [4 x i8] zeroinitializer, align 4
; BAD: Warning: Default global prefix 'g' conflicts with name 'g'.
define i32 @2(i32 %v) {
ret i32 %v
}
; CHECK: define i32 @Function(i32 %__0) {
; CHECK-NEXT: __0:
; CHECK-NEXT: ret i32 %__0
; CHECK-NEXT: }
define void @hg() {
ret void
}
; BAD: Warning: Default function prefix 'h' conflicts with name 'hg'.
; CHECK-NEXT: define void @hg() {
; CHECK-NEXT: __0:
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @3() {
ret void
}
; CHECK-NEXT: define void @Function1() {
; CHECK-NEXT: __0:
; CHECK-NEXT: ret void
; CHECK-NEXT: }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment