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 @@
#ifndef SUBZERO_SRC_ICECLFLAGS_H
#define SUBZERO_SRC_ICECLFLAGS_H
#include "IceTypes.def"
namespace Ice {
// TODO(stichnot) Move more command line flags into ClFlags.
class ClFlags {
public:
ClFlags()
: DisableInternal(false), SubzeroTimingEnabled(false),
DisableTranslation(false), DisableGlobals(false),
FunctionSections(false), UseSandboxing(false) {}
FunctionSections(false), UseSandboxing(false), DefaultGlobalPrefix(""),
DefaultFunctionPrefix("") {}
bool DisableInternal;
bool SubzeroTimingEnabled;
bool DisableTranslation;
bool DisableGlobals;
bool FunctionSections;
bool UseSandboxing;
IceString DefaultGlobalPrefix;
IceString DefaultFunctionPrefix;
};
} // end of namespace Ice
......
......@@ -608,6 +608,7 @@ private:
namespace Ice {
void Converter::convertToIce() {
nameUnnamedGlobalAddresses(Mod);
if (!Ctx->getFlags().DisableGlobals)
convertGlobals();
convertFunctions();
......
......@@ -16,7 +16,9 @@
#include "IceCfg.h"
#include "IceClFlags.h"
#include "IceDefs.h"
#include "IceTargetLowering.h"
#include "llvm/IR/Module.h"
#include <iostream>
......@@ -24,14 +26,58 @@ using namespace Ice;
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);
if (Ctx->getFlags().DisableInternal)
Func->setInternal(false);
if (Ctx->getFlags().DisableTranslation) {
Func->dump();
} else {
Ice::Timer TTranslate;
Timer TTranslate;
Func->translate();
if (Ctx->getFlags().SubzeroTimingEnabled) {
std::cerr << "[Subzero timing] Translate function "
......@@ -43,7 +89,7 @@ void Translator::translateFcn(Ice::Cfg *Fcn) {
ErrorStatus = true;
}
Ice::Timer TEmit;
Timer TEmit;
Func->emit();
if (Ctx->getFlags().SubzeroTimingEnabled) {
std::cerr << "[Subzero timing] Emit function " << Func->getFunctionName()
......
......@@ -17,6 +17,10 @@
#include "llvm/ADT/OwningPtr.h"
namespace llvm {
class Module;
}
namespace Ice {
class ClFlags;
......@@ -47,6 +51,11 @@ public:
/// Emits the constant pool.
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:
GlobalContext *Ctx;
const ClFlags &Flags;
......
......@@ -1887,11 +1887,14 @@ bool FunctionParser::ParseBlock(unsigned BlockID) {
class ModuleParser : public BlockParserBaseClass {
public:
ModuleParser(unsigned BlockID, TopLevelParser *Context)
: BlockParserBaseClass(BlockID, Context) {}
: BlockParserBaseClass(BlockID, Context), FoundFirstFunctionBlock(false) {
}
virtual ~ModuleParser() LLVM_OVERRIDE {}
protected:
private:
// True if we have parsed a function block.
bool FoundFirstFunctionBlock;
virtual bool ParseBlock(unsigned BlockID) LLVM_OVERRIDE;
virtual void ProcessRecord() LLVM_OVERRIDE;
......@@ -1950,6 +1953,10 @@ bool ModuleParser::ParseBlock(unsigned BlockID) LLVM_OVERRIDE {
return Parser.ParseThisBlock();
}
case naclbitc::FUNCTION_BLOCK_ID: {
if (!FoundFirstFunctionBlock) {
getTranslator().nameUnnamedGlobalAddresses(Context->getModule());
FoundFirstFunctionBlock = true;
}
FunctionParser Parser(BlockID, this);
return Parser.ParseThisBlock();
}
......
......@@ -109,6 +109,18 @@ static cl::opt<NaClFileFormat> InputFileFormat(
clEnumValEnd),
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>
BuildOnRead("build-on-read",
cl::desc("Build ICE instructions when reading bitcode"),
......@@ -143,6 +155,8 @@ int main(int argc, char **argv) {
Flags.DisableGlobals = DisableGlobals;
Flags.FunctionSections = FunctionSections;
Flags.UseSandboxing = UseSandboxing;
Flags.DefaultGlobalPrefix = DefaultGlobalPrefix;
Flags.DefaultFunctionPrefix = DefaultFunctionPrefix;
Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix,
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