Commit 9d98d791 by Karl Schimpf

Introduce the notion of function addresses in Subzero.

Introduces the notion of a function address, to replace using LLVM IR's Function class. Modifies Ice converter, and Subzero's bitcode reader, to build function addresses. BUG=None R=jvoung@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/641193002
parent d026c448
...@@ -23,6 +23,16 @@ namespace Subzero_ { ...@@ -23,6 +23,16 @@ namespace Subzero_ {
#include "test_global.h" #include "test_global.h"
} }
int ExternName1 = 36363;
float ExternName2 = 357.05e-10;
char ExternName3[] = {'a', 'b', 'c'};
struct {
int a;
float b;
double d;
} ExternName4 = {-111, 2.69, 55.19};
double ExternName5 = 3.44e26;
int main(int argc, char **argv) { int main(int argc, char **argv) {
size_t TotalTests = 0; size_t TotalTests = 0;
size_t Passes = 0; size_t Passes = 0;
......
...@@ -14,9 +14,11 @@ ...@@ -14,9 +14,11 @@
#ifndef SUBZERO_SRC_ICECONVERTER_H #ifndef SUBZERO_SRC_ICECONVERTER_H
#define SUBZERO_SRC_ICECONVERTER_H #define SUBZERO_SRC_ICECONVERTER_H
#include "IceDefs.h"
#include "IceTranslator.h" #include "IceTranslator.h"
namespace llvm { namespace llvm {
class GlobalValue;
class Module; class Module;
} }
...@@ -27,18 +29,42 @@ public: ...@@ -27,18 +29,42 @@ public:
Converter(llvm::Module *Mod, GlobalContext *Ctx, const Ice::ClFlags &Flags) Converter(llvm::Module *Mod, GlobalContext *Ctx, const Ice::ClFlags &Flags)
: Translator(Ctx, Flags), Mod(Mod) {} : Translator(Ctx, Flags), Mod(Mod) {}
~Converter() {}
/// Converts the LLVM Module to ICE. Sets exit status to false if successful, /// Converts the LLVM Module to ICE. Sets exit status to false if successful,
/// true otherwise. /// true otherwise.
void convertToIce(); void convertToIce();
llvm::Module *getModule() const { return Mod; }
// Returns the global declaration associated with the corresponding
// global value V. If no such global address, generates fatal error.
GlobalDeclaration *getGlobalDeclaration(const llvm::GlobalValue *V);
private: private:
llvm::Module *Mod; llvm::Module *Mod;
typedef std::map<const llvm::GlobalValue *, GlobalDeclaration *>
GlobalDeclarationMapType;
GlobalDeclarationMapType GlobalDeclarationMap;
// Walks module and generates names for unnamed globals using prefix
// getFlags().DefaultGlobalPrefix, if the prefix is non-empty.
void nameUnnamedGlobalVariables(llvm::Module *Mod);
// Walks module and generates names for unnamed functions using
// prefix getFlags().DefaultFunctionPrefix, if the prefix is
// non-empty.
void nameUnnamedFunctions(llvm::Module *Mod);
// Converts functions to ICE, and then machine code. // Converts functions to ICE, and then machine code.
void convertFunctions(); void convertFunctions();
// Converts globals to ICE, and then machine code. // Converts globals to ICE, and then machine code.
void convertGlobals(llvm::Module *Mod); void convertGlobals(llvm::Module *Mod);
// Installs global declarations into GlobalDeclarationMap.
void installGlobalDeclarations(llvm::Module *Mod);
Converter(const Converter &) = delete; Converter(const Converter &) = delete;
Converter &operator=(const Converter &) = delete; Converter &operator=(const Converter &) = delete;
}; };
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <set> #include <set>
#include <string> #include <string>
#include <vector> #include <vector>
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h" #include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallBitVector.h"
...@@ -39,7 +38,9 @@ namespace Ice { ...@@ -39,7 +38,9 @@ namespace Ice {
class Cfg; class Cfg;
class CfgNode; class CfgNode;
class Constant; class Constant;
class FunctionDeclaration;
class GlobalContext; class GlobalContext;
class GlobalDeclaration;
class Inst; class Inst;
class InstPhi; class InstPhi;
class InstTarget; class InstTarget;
...@@ -48,6 +49,7 @@ class Liveness; ...@@ -48,6 +49,7 @@ class Liveness;
class Operand; class Operand;
class TargetLowering; class TargetLowering;
class Variable; class Variable;
class VariableDeclaration;
class VariablesMetadata; class VariablesMetadata;
// TODO: Switch over to LLVM's ADT container classes. // TODO: Switch over to LLVM's ADT container classes.
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "IceClFlags.h" #include "IceClFlags.h"
#include "IceDefs.h" #include "IceDefs.h"
#include "IceGlobalContext.h" #include "IceGlobalContext.h"
#include "IceGlobalInits.h"
#include "IceOperand.h" #include "IceOperand.h"
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
#include "IceTimerTree.h" #include "IceTimerTree.h"
...@@ -289,7 +290,9 @@ IceString GlobalContext::mangleName(const IceString &Name) const { ...@@ -289,7 +290,9 @@ IceString GlobalContext::mangleName(const IceString &Name) const {
return getTestPrefix() + Name; return getTestPrefix() + Name;
} }
GlobalContext::~GlobalContext() {} GlobalContext::~GlobalContext() {
llvm::DeleteContainerPointers(GlobalDeclarations);
}
Constant *GlobalContext::getConstantInt64(Type Ty, uint64_t ConstantInt64) { Constant *GlobalContext::getConstantInt64(Type Ty, uint64_t ConstantInt64) {
assert(Ty == IceType_i64); assert(Ty == IceType_i64);
...@@ -385,6 +388,23 @@ ConstantList GlobalContext::getConstantPool(Type Ty) const { ...@@ -385,6 +388,23 @@ ConstantList GlobalContext::getConstantPool(Type Ty) const {
llvm_unreachable("Unknown type"); llvm_unreachable("Unknown type");
} }
FunctionDeclaration *
GlobalContext::newFunctionDeclaration(const FuncSigType *Signature,
unsigned CallingConv, unsigned Linkage,
bool IsProto) {
FunctionDeclaration *Func = new FunctionDeclaration(
*Signature, static_cast<llvm::CallingConv::ID>(CallingConv),
static_cast<llvm::GlobalValue::LinkageTypes>(Linkage), IsProto);
GlobalDeclarations.push_back(Func);
return Func;
}
VariableDeclaration *GlobalContext::newVariableDeclaration() {
VariableDeclaration *Var = new VariableDeclaration();
GlobalDeclarations.push_back(Var);
return Var;
}
TimerIdT GlobalContext::getTimerID(TimerStackIdT StackID, TimerIdT GlobalContext::getTimerID(TimerStackIdT StackID,
const IceString &Name) { const IceString &Name) {
assert(StackID < Timers.size()); assert(StackID < Timers.size());
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "IceDefs.h" #include "IceDefs.h"
#include "IceClFlags.h"
#include "IceIntrinsics.h" #include "IceIntrinsics.h"
#include "IceRNG.h" #include "IceRNG.h"
#include "IceTimerTree.h" #include "IceTimerTree.h"
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
namespace Ice { namespace Ice {
class ClFlags; class ClFlags;
class FuncSigType;
// This class collects rudimentary statistics during translation. // This class collects rudimentary statistics during translation.
class CodeStats { class CodeStats {
...@@ -117,6 +119,17 @@ public: ...@@ -117,6 +119,17 @@ public:
// getConstantPool() returns a copy of the constant pool for // getConstantPool() returns a copy of the constant pool for
// constants of a given type. // constants of a given type.
ConstantList getConstantPool(Type Ty) const; ConstantList getConstantPool(Type Ty) const;
// Returns a new function declaration, allocated in an internal
// memory pool. Ownership of the function is maintained by this
// class instance.
FunctionDeclaration *newFunctionDeclaration(const FuncSigType *Signature,
unsigned CallingConv,
unsigned Linkage, bool IsProto);
// Returns a new global variable declaration, allocated in an
// internal memory pool. Ownership of the function is maintained by
// this class instance.
VariableDeclaration *newVariableDeclaration();
const ClFlags &getFlags() const { return Flags; } const ClFlags &getFlags() const { return Flags; }
...@@ -186,6 +199,7 @@ private: ...@@ -186,6 +199,7 @@ private:
CodeStats StatsFunction; CodeStats StatsFunction;
CodeStats StatsCumulative; CodeStats StatsCumulative;
std::vector<TimerStack> Timers; std::vector<TimerStack> Timers;
std::vector<GlobalDeclaration *> GlobalDeclarations;
GlobalContext(const GlobalContext &) = delete; GlobalContext(const GlobalContext &) = delete;
GlobalContext &operator=(const GlobalContext &) = delete; GlobalContext &operator=(const GlobalContext &) = delete;
......
//===- subzero/src/IceGlobalInits.cpp - Global initializers ---------------===// //===- subzero/src/IceGlobalInits.cpp - Global declarations ---------------===//
// //
// The Subzero Code Generator // The Subzero Code Generator
// //
...@@ -7,8 +7,9 @@ ...@@ -7,8 +7,9 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This file implements the notion of global addresses and // This file implements the notion of function declarations, global
// initializers in Subzero. // variable declarations, and the corresponding variable initializers
// in Subzero.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
...@@ -17,18 +18,82 @@ ...@@ -17,18 +18,82 @@
#include "llvm/IR/Value.h" #include "llvm/IR/Value.h"
#include "IceDefs.h" #include "IceDefs.h"
#include "IceGlobalContext.h"
#include "IceGlobalInits.h" #include "IceGlobalInits.h"
#include "IceTypes.h" #include "IceTypes.h"
namespace { namespace {
char hexdigit(unsigned X) { return X < 10 ? '0' + X : 'A' + X - 10; } char hexdigit(unsigned X) { return X < 10 ? '0' + X : 'A' + X - 10; }
void dumpLinkage(Ice::Ostream &Stream,
llvm::GlobalValue::LinkageTypes Linkage) {
switch (Linkage) {
case llvm::GlobalValue::ExternalLinkage:
Stream << "external";
return;
case llvm::GlobalValue::InternalLinkage:
Stream << "internal";
return;
default:
break;
}
std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer);
StrBuf << "Unknown linkage value: " << Linkage;
llvm::report_fatal_error(StrBuf.str());
}
void dumpCallingConv(Ice::Ostream &, llvm::CallingConv::ID CallingConv) {
if (CallingConv == llvm::CallingConv::C)
return;
std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer);
StrBuf << "Unknown calling convention: " << CallingConv;
llvm::report_fatal_error(StrBuf.str());
} }
} // end of anonymous namespace
namespace Ice { namespace Ice {
GlobalAddress::~GlobalAddress() { llvm::DeleteContainerPointers(Initializers); } FunctionDeclaration *
FunctionDeclaration::create(GlobalContext *Ctx, const FuncSigType &Signature,
llvm::CallingConv::ID CallingConv,
llvm::GlobalValue::LinkageTypes Linkage,
bool IsProto) {
return Ctx->newFunctionDeclaration(&Signature, CallingConv, Linkage, IsProto);
}
void GlobalAddress::dumpType(Ostream &Stream) const { void FunctionDeclaration::dumpType(Ostream &Stream) const {
Stream << Signature;
}
void FunctionDeclaration::dump(Ostream &Stream) const {
if (IsProto)
Stream << "declare ";
::dumpLinkage(Stream, Linkage);
::dumpCallingConv(Stream, CallingConv);
Stream << Signature.getReturnType() << " @" << Name << "(";
bool IsFirst = true;
for (Type ArgTy : Signature.getArgList()) {
if (IsFirst)
IsFirst = false;
else
Stream << ", ";
Stream << ArgTy;
}
Stream << ")";
}
VariableDeclaration *VariableDeclaration::create(GlobalContext *Ctx) {
return Ctx->newVariableDeclaration();
}
VariableDeclaration::~VariableDeclaration() {
llvm::DeleteContainerPointers(Initializers);
}
void VariableDeclaration::dumpType(Ostream &Stream) const {
if (Initializers.size() == 1) { if (Initializers.size() == 1) {
Initializers.front()->dumpType(Stream); Initializers.front()->dumpType(Stream);
} else { } else {
...@@ -46,8 +111,8 @@ void GlobalAddress::dumpType(Ostream &Stream) const { ...@@ -46,8 +111,8 @@ void GlobalAddress::dumpType(Ostream &Stream) const {
} }
} }
void GlobalAddress::dump(Ostream &Stream) const { void VariableDeclaration::dump(Ostream &Stream) const {
Stream << "@" << getName() << " = internal " Stream << "@" << Name << " = internal "
<< (IsConstant ? "constant" : "global") << " "; << (IsConstant ? "constant" : "global") << " ";
// Add initializer. // Add initializer.
...@@ -74,11 +139,11 @@ void GlobalAddress::dump(Ostream &Stream) const { ...@@ -74,11 +139,11 @@ void GlobalAddress::dump(Ostream &Stream) const {
Stream << "\n"; Stream << "\n";
} }
void GlobalAddress::Initializer::dumpType(Ostream &Stream) const { void VariableDeclaration::Initializer::dumpType(Ostream &Stream) const {
Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]"; Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]";
} }
void GlobalAddress::DataInitializer::dump(Ostream &Stream) const { void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const {
dumpType(Stream); dumpType(Stream);
Stream << " c\""; Stream << " c\"";
// Code taken from PrintEscapedString() in AsmWriter.cpp. Keep // Code taken from PrintEscapedString() in AsmWriter.cpp. Keep
...@@ -93,41 +158,24 @@ void GlobalAddress::DataInitializer::dump(Ostream &Stream) const { ...@@ -93,41 +158,24 @@ void GlobalAddress::DataInitializer::dump(Ostream &Stream) const {
Stream << "\""; Stream << "\"";
} }
void GlobalAddress::ZeroInitializer::dump(Ostream &Stream) const { void VariableDeclaration::ZeroInitializer::dump(Ostream &Stream) const {
dumpType(Stream); dumpType(Stream);
Stream << " zeroinitializer"; Stream << " zeroinitializer";
} }
IceString GlobalAddress::RelocInitializer::getName() const { void VariableDeclaration::RelocInitializer::dumpType(Ostream &Stream) const {
switch (Address.getKind()) {
case FunctionRelocation:
return Address.getFunction()->getName();
case GlobalAddressRelocation:
return Address.getGlobalAddr()->getName();
default:
llvm::report_fatal_error("Malformed relocation address!");
}
}
void GlobalAddress::RelocInitializer::dumpType(Ostream &Stream) const {
Stream << Ice::IceType_i32; Stream << Ice::IceType_i32;
} }
void GlobalAddress::RelocInitializer::dump(Ostream &Stream) const { void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const {
if (Offset != 0) { if (Offset != 0) {
dumpType(Stream); dumpType(Stream);
Stream << " add ("; Stream << " add (";
} }
dumpType(Stream); dumpType(Stream);
Stream << " ptrtoint ("; Stream << " ptrtoint (";
if (Address.getKind() == FunctionRelocation) { Declaration->dumpType(Stream);
Stream << *Address.getFunction()->getType() << " @" Stream << "* @" << Declaration->getName() << " to ";
<< Address.getFunction()->getName();
} else {
Address.getGlobalAddr()->dumpType(Stream);
Stream << "* @" << Address.getGlobalAddr()->getName();
}
Stream << " to ";
dumpType(Stream); dumpType(Stream);
Stream << ")"; Stream << ")";
if (Offset != 0) { if (Offset != 0) {
...@@ -136,4 +184,5 @@ void GlobalAddress::RelocInitializer::dump(Ostream &Stream) const { ...@@ -136,4 +184,5 @@ void GlobalAddress::RelocInitializer::dump(Ostream &Stream) const {
Stream << " " << Offset << ")"; Stream << " " << Offset << ")";
} }
} }
}
} // end of namespace Ice
...@@ -27,7 +27,6 @@ namespace Ice { ...@@ -27,7 +27,6 @@ namespace Ice {
typedef uint8_t AsmCodeByte; typedef uint8_t AsmCodeByte;
class Assembler; class Assembler;
class GlobalAddress;
// LoweringContext makes it easy to iterate through non-deleted // LoweringContext makes it easy to iterate through non-deleted
// instructions in a node, and insert new (lowered) instructions at // instructions in a node, and insert new (lowered) instructions at
...@@ -249,7 +248,7 @@ public: ...@@ -249,7 +248,7 @@ public:
GlobalContext *Ctx); GlobalContext *Ctx);
virtual ~TargetGlobalInitLowering(); virtual ~TargetGlobalInitLowering();
virtual void lower(const GlobalAddress &Addr, bool DisableTranslation) = 0; virtual void lower(const VariableDeclaration &Var) = 0;
protected: protected:
TargetGlobalInitLowering(GlobalContext *Ctx) : Ctx(Ctx) {} TargetGlobalInitLowering(GlobalContext *Ctx) : Ctx(Ctx) {}
......
...@@ -4427,32 +4427,19 @@ void ConstantUndef::emit(GlobalContext *) const { ...@@ -4427,32 +4427,19 @@ void ConstantUndef::emit(GlobalContext *) const {
TargetGlobalInitX8632::TargetGlobalInitX8632(GlobalContext *Ctx) TargetGlobalInitX8632::TargetGlobalInitX8632(GlobalContext *Ctx)
: TargetGlobalInitLowering(Ctx) {} : TargetGlobalInitLowering(Ctx) {}
void TargetGlobalInitX8632::lower(const GlobalAddress &Global, void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
bool DisableTranslation) {
if (Ctx->isVerbose()) {
Global.dump(Ctx->getStrDump());
}
if (DisableTranslation)
return;
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
// TODO(kschimpf): Don't mangle name if external and uninitialized. This const VariableDeclaration::InitializerListType &Initializers =
// will allow us to cross test relocations for references to external Var.getInitializers();
// global variables.
const GlobalAddress::InitializerListType &Initializers =
Global.getInitializers();
assert(Initializers.size()); assert(Initializers.size());
bool HasInitializer = bool HasInitializer = Var.hasInitializer();
!(Initializers.size() == 1 && bool IsConstant = Var.getIsConstant();
llvm::isa<GlobalAddress::ZeroInitializer>(Initializers[0])); bool IsExternal = Var.getIsExternal();
bool IsConstant = Global.getIsConstant(); uint32_t Align = Var.getAlignment();
bool IsExternal = !Global.getIsInternal(); SizeT Size = Var.getNumBytes();
uint32_t Align = Global.getAlignment(); IceString MangledName = Var.mangleName(Ctx);
SizeT Size = Global.getNumBytes();
IceString MangledName = Ctx->mangleName(Global.getName());
IceString SectionSuffix = ""; IceString SectionSuffix = "";
if (Ctx->getFlags().DataSections) if (Ctx->getFlags().DataSections)
SectionSuffix = "." + MangledName; SectionSuffix = "." + MangledName;
...@@ -4483,30 +4470,29 @@ void TargetGlobalInitX8632::lower(const GlobalAddress &Global, ...@@ -4483,30 +4470,29 @@ void TargetGlobalInitX8632::lower(const GlobalAddress &Global,
Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n"; Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n";
if (HasInitializer) { if (HasInitializer) {
for (GlobalAddress::Initializer *Init : Initializers) { for (VariableDeclaration::Initializer *Init : Initializers) {
switch (Init->getKind()) { switch (Init->getKind()) {
case GlobalAddress::Initializer::DataInitializerKind: { case VariableDeclaration::Initializer::DataInitializerKind: {
const auto Data = const auto Data = llvm::cast<VariableDeclaration::DataInitializer>(Init)
llvm::cast<GlobalAddress::DataInitializer>(Init)->getContents(); ->getContents();
for (SizeT i = 0; i < Init->getNumBytes(); ++i) { for (SizeT i = 0; i < Init->getNumBytes(); ++i) {
Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
} }
break; break;
} }
case GlobalAddress::Initializer::ZeroInitializerKind: case VariableDeclaration::Initializer::ZeroInitializerKind:
Str << "\t.zero\t" << Init->getNumBytes() << "\n"; Str << "\t.zero\t" << Init->getNumBytes() << "\n";
break; break;
case GlobalAddress::Initializer::RelocInitializerKind: { case VariableDeclaration::Initializer::RelocInitializerKind: {
const auto Reloc = llvm::cast<GlobalAddress::RelocInitializer>(Init); const auto Reloc =
llvm::cast<VariableDeclaration::RelocInitializer>(Init);
Str << "\t.long\t"; Str << "\t.long\t";
// TODO(kschimpf): Once the representation of a relocation has Str << Reloc->getDeclaration()->mangleName(Ctx);
// been modified to reference the corresponding global if (VariableDeclaration::RelocOffsetType Offset = Reloc->getOffset()) {
// address, modify to not mangle the name if the global is if (Offset >= 0 || (Offset == INT32_MIN))
// external and uninitialized. This will allow us to better
// test cross test relocations.
Str << Ctx->mangleName(Reloc->getName());
if (GlobalAddress::RelocOffsetType Offset = Reloc->getOffset()) {
Str << " + " << Offset; Str << " + " << Offset;
else
Str << " - " << -Offset;
} }
Str << "\n"; Str << "\n";
break; break;
......
...@@ -482,8 +482,7 @@ public: ...@@ -482,8 +482,7 @@ public:
return new TargetGlobalInitX8632(Ctx); return new TargetGlobalInitX8632(Ctx);
} }
virtual void lower(const GlobalAddress &Addr, virtual void lower(const VariableDeclaration &Var) final;
bool DisableTranslation) override;
protected: protected:
TargetGlobalInitX8632(GlobalContext *Ctx); TargetGlobalInitX8632(GlobalContext *Ctx);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "IceCfg.h" #include "IceCfg.h"
#include "IceClFlags.h" #include "IceClFlags.h"
#include "IceDefs.h" #include "IceDefs.h"
#include "IceGlobalInits.h"
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
#include "IceTranslator.h" #include "IceTranslator.h"
...@@ -54,38 +55,6 @@ bool Translator::checkIfUnnamedNameSafe(const IceString &Name, const char *Kind, ...@@ -54,38 +55,6 @@ bool Translator::checkIfUnnamedNameSafe(const IceString &Name, const char *Kind,
return false; return false;
} }
void Translator::nameUnnamedGlobalAddresses(llvm::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 Translator::nameUnnamedFunctions(llvm::Module *Mod) {
const IceString &FunctionPrefix = Flags.DefaultFunctionPrefix;
if (FunctionPrefix.empty())
return;
uint32_t NameIndex = 0;
Ostream &errs = Ctx->getStrDump();
for (llvm::Function &F : *Mod) {
if (!F.hasName()) {
F.setName(createUnnamedName(FunctionPrefix, NameIndex));
++NameIndex;
} else {
checkIfUnnamedNameSafe(F.getName(), "function", FunctionPrefix, errs);
}
}
}
void Translator::translateFcn(Cfg *Fcn) { void Translator::translateFcn(Cfg *Fcn) {
Ctx->resetStats(); Ctx->resetStats();
Func.reset(Fcn); Func.reset(Fcn);
...@@ -110,12 +79,18 @@ void Translator::emitConstants() { ...@@ -110,12 +79,18 @@ void Translator::emitConstants() {
Func->getTarget()->emitConstants(); Func->getTarget()->emitConstants();
} }
void Translator::lowerGlobals(const GlobalAddressList &GlobalAddresses) { void Translator::lowerGlobals(
llvm::OwningPtr<Ice::TargetGlobalInitLowering> GlobalLowering( const VariableDeclarationListType &VariableDeclarations) {
Ice::TargetGlobalInitLowering::createLowering(Ctx->getTargetArch(), Ctx)); llvm::OwningPtr<TargetGlobalInitLowering> GlobalLowering(
TargetGlobalInitLowering::createLowering(Ctx->getTargetArch(), Ctx));
bool DisableTranslation = Ctx->getFlags().DisableTranslation; bool DisableTranslation = Ctx->getFlags().DisableTranslation;
for (const Ice::GlobalAddress *Addr : GlobalAddresses) { bool DumpGlobalVariables = Ctx->isVerbose();
GlobalLowering->lower(*Addr, DisableTranslation); Ostream &Stream = Ctx->getStrDump();
for (const Ice::VariableDeclaration *Global : VariableDeclarations) {
if (DumpGlobalVariables)
Global->dump(Stream);
if(!DisableTranslation)
GlobalLowering->lower(*Global);
} }
GlobalLowering.reset(); GlobalLowering.reset();
} }
...@@ -25,16 +25,15 @@ namespace Ice { ...@@ -25,16 +25,15 @@ namespace Ice {
class ClFlags; class ClFlags;
class Cfg; class Cfg;
class GlobalAddress; class VariableDeclaration;
class GlobalContext; class GlobalContext;
// Base class for translating ICE to machine code. // Base class for translating ICE to machine code. Derived classes convert
// Derived classes convert other intermediate representations down to ICE, // other intermediate representations down to ICE, and then call the appropriate
// and then call the appropriate (inherited) methods to convert ICE into // (inherited) methods to convert ICE into machine instructions.
// machine instructions.
class Translator { class Translator {
public: public:
typedef std::vector<Ice::GlobalAddress *> GlobalAddressList; typedef std::vector<VariableDeclaration *> VariableDeclarationListType;
Translator(GlobalContext *Ctx, const ClFlags &Flags) Translator(GlobalContext *Ctx, const ClFlags &Flags)
: Ctx(Ctx), Flags(Flags), ErrorStatus(0) {} : Ctx(Ctx), Flags(Flags), ErrorStatus(0) {}
...@@ -54,8 +53,9 @@ public: ...@@ -54,8 +53,9 @@ public:
/// Emits the constant pool. /// Emits the constant pool.
void emitConstants(); void emitConstants();
/// Lowers the given list of global addresses to target. /// Lowers the given list of global addresses to target. Generates
void lowerGlobals(const GlobalAddressList &GlobalAddresses); /// list of corresponding variable declarations.
void lowerGlobals(const VariableDeclarationListType &VariableDeclarations);
/// Creates a name using the given prefix and corresponding index. /// Creates a name using the given prefix and corresponding index.
std::string createUnnamedName(const IceString &Prefix, SizeT Index); std::string createUnnamedName(const IceString &Prefix, SizeT Index);
...@@ -66,15 +66,6 @@ public: ...@@ -66,15 +66,6 @@ public:
bool checkIfUnnamedNameSafe(const IceString &Name, const char *Kind, bool checkIfUnnamedNameSafe(const IceString &Name, const char *Kind,
const IceString &Prefix, Ostream &Stream); const IceString &Prefix, Ostream &Stream);
// Walks module and generates names for unnamed globals using prefix
// getFlags().DefaultGlobalPrefix, if the prefix is non-empty.
void nameUnnamedGlobalAddresses(llvm::Module *Mod);
// Walks module and generates names for unnamed functions using
// prefix getFlags().DefaultFunctionPrefix, if the prefix is
// non-empty.
void nameUnnamedFunctions(llvm::Module *Mod);
protected: protected:
GlobalContext *Ctx; GlobalContext *Ctx;
const ClFlags &Flags; const ClFlags &Flags;
......
; Test of global initializers. ; Test of global initializers.
; Check that we generate proper global initializers. ; Check that we generate proper global initializers.
; RUN: %p2i -i %s --args -verbose inst | FileCheck %s ; RUN: %l2i -i %s --insts | FileCheck %s
; RUN: %p2i -i %s --insts | FileCheck %s
; Check that what we generate is valid assembly
; RUN: %p2i -i %s --args -verbose none \
; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj
; Check that we don't generate errors
; RUN: %p2i -i %s --args -verbose none | FileCheck --check-prefix=ERRORS %s
@PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4 @PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
; CHECK: .type PrimitiveInit,@object ; CHECK: @PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: PrimitiveInit:
; CHECK-NEXT: .byte
; CHECK: .size PrimitiveInit, 4
@PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4 @PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4
; CHECK: .type PrimitiveInitConst,@object ; CHECK-NEXT: @PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4
; CHECK-NEXT: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: PrimitiveInitConst:
; CHECK-NEXT: .byte
; CHECK: .size PrimitiveInitConst, 4
@ArrayInit = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4 @ArrayInit = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4
; CHECK: .type ArrayInit,@object ; CHECK-NEXT: @ArrayInit = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4
; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayInit:
; CHECK-NEXT: .byte
; CHECK: .size ArrayInit, 20
@ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4 @ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
; CHECK: .type ArrayInitPartial,@object ; CHECK-NEXT: @ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayInitPartial:
; CHECK-NEXT: .byte
; CHECK: .size ArrayInitPartial, 40
@PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4 @PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .type PrimitiveInitStatic,@object ; CHECK-NEXT: @PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4
; CHECK-NEXT: .local PrimitiveInitStatic
; CHECK-NEXT: .comm PrimitiveInitStatic,4,4
@PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4 @PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .type PrimitiveUninit,@object ; CHECK-NEXT: @PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4
; CHECK-NEXT: .local PrimitiveUninit
; CHECK-NEXT: .comm PrimitiveUninit,4,4
@ArrayUninit = internal global [20 x i8] zeroinitializer, align 4 @ArrayUninit = internal global [20 x i8] zeroinitializer, align 4
; CHECK: .type ArrayUninit,@object ; CHECK-NEXT: @ArrayUninit = internal global [20 x i8] zeroinitializer, align 4
; CHECK-NEXT: .local ArrayUninit
; CHECK-NEXT: .comm ArrayUninit,20,4
@ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8 @ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8
; CHECK: .type ArrayUninitConstDouble,@object ; CHECK-NEXT: @ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8
; CHECK-NEXT: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 8
; CHECK-NEXT: ArrayUninitConstDouble:
; CHECK-NEXT: .zero 200
; CHECK-NEXT: .size ArrayUninitConstDouble, 200
@ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4 @ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4
; CHECK: .type ArrayUninitConstInt,@object ; CHECK-NEXT: @ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4
; CHECK: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayUninitConstInt:
; CHECK-NEXT: .zero 20
; CHECK-NEXT: .size ArrayUninitConstInt, 20
@__init_array_start = internal constant [0 x i8] zeroinitializer, align 4 @__init_array_start = internal constant [0 x i8] zeroinitializer, align 4
; CHECK-NEXT: @__init_array_start = internal constant [0 x i8] zeroinitializer, align 4
@__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4 @__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4
; CHECK: @__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4
@__tls_template_start = internal constant [0 x i8] zeroinitializer, align 8 @__tls_template_start = internal constant [0 x i8] zeroinitializer, align 8
; CHECK: @__tls_template_start = internal constant [0 x i8] zeroinitializer, align 8
@__tls_template_alignment = internal constant [4 x i8] c"\01\00\00\00", align 4 @__tls_template_alignment = internal constant [4 x i8] c"\01\00\00\00", align 4
; CHECK: @__tls_template_alignment = internal constant [4 x i8] c"\01\00\00\00", align 4
define internal i32 @main(i32 %argc, i32 %argv) { define internal i32 @main(i32 %argc, i32 %argv) {
entry: entry:
...@@ -96,28 +61,6 @@ entry: ...@@ -96,28 +61,6 @@ entry:
call void @use(i32 %expanded13) call void @use(i32 %expanded13)
ret i32 0 ret i32 0
} }
; CHECK-LABEL: main
; CHECK: .att_syntax
; CHECK: leal PrimitiveInit,
; CHECK: .intel_syntax
; CHECK: .att_syntax
; CHECK: leal PrimitiveInitConst,
; CHECK: .intel_syntax
; CHECK: .att_syntax
; CHECK: leal PrimitiveInitStatic,
; CHECK: .intel_syntax
; CHECK: .att_syntax
; CHECK: leal PrimitiveUninit,
; CHECK: .intel_syntax
; CHECK: .att_syntax
; CHECK: leal ArrayInit,
; CHECK: .intel_syntax
; CHECK: .att_syntax
; CHECK: leal ArrayInitPartial,
; CHECK: .intel_syntax
; CHECK: .att_syntax
; CHECK: leal ArrayUninit,
; CHECK: .intel_syntax
declare void @use(i32) declare void @use(i32)
......
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