Commit df6f9d18 by Karl Schimpf

Fix handling of relocation names, so that prefix mangling works.

Fixes bug in the representation of relocation names (in either global initializers or as constant expressions in code) so that they understand when the name is externally defined. This allows us to test this property using command line arguments, and fixes relocation tests in cross compilations (where externnally referenced names shouldn't be name mangled). BUG= R=jvoung@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/667763002
parent f76fd377
...@@ -45,9 +45,9 @@ namespace Subzero_ { ...@@ -45,9 +45,9 @@ namespace Subzero_ {
// functions receive arguments from the caller in the same way. The // functions receive arguments from the caller in the same way. The
// caller is compiled by llc. // caller is compiled by llc.
size_t ArgNum, Subzero_ArgNum; size_t ArgNum;
CalleePtrTy Callee, Subzero_Callee; CalleePtrTy Callee;
char *Buf, *Subzero_Buf; char *Buf;
const static size_t BUF_SIZE = 16; const static size_t BUF_SIZE = 16;
...@@ -83,13 +83,13 @@ void testCaller(size_t &TotalTests, size_t &Passes, size_t &Failures) { ...@@ -83,13 +83,13 @@ void testCaller(size_t &TotalTests, size_t &Passes, size_t &Failures) {
for (size_t f = 0; f < NumFuncs; ++f) { for (size_t f = 0; f < NumFuncs; ++f) {
char BufLlc[BUF_SIZE], BufSz[BUF_SIZE]; char BufLlc[BUF_SIZE], BufSz[BUF_SIZE];
Callee = Subzero_Callee = Funcs[f].Callee; Callee = Funcs[f].Callee;
for (size_t i = 0; i < Funcs[f].Args; ++i) { for (size_t i = 0; i < Funcs[f].Args; ++i) {
memset(BufLlc, 0xff, sizeof(BufLlc)); memset(BufLlc, 0xff, sizeof(BufLlc));
memset(BufSz, 0xff, sizeof(BufSz)); memset(BufSz, 0xff, sizeof(BufSz));
ArgNum = Subzero_ArgNum = i; ArgNum = i;
Buf = BufLlc; Buf = BufLlc;
Funcs[f].Caller(); Funcs[f].Caller();
...@@ -133,18 +133,18 @@ void testCallee(size_t &TotalTests, size_t &Passes, size_t &Failures) { ...@@ -133,18 +133,18 @@ void testCallee(size_t &TotalTests, size_t &Passes, size_t &Failures) {
for (size_t f = 0; f < NumFuncs; ++f) { for (size_t f = 0; f < NumFuncs; ++f) {
char BufLlc[BUF_SIZE], BufSz[BUF_SIZE]; char BufLlc[BUF_SIZE], BufSz[BUF_SIZE];
Buf = BufLlc;
Subzero_Buf = BufSz;
for (size_t i = 0; i < Funcs[f].Args; ++i) { for (size_t i = 0; i < Funcs[f].Args; ++i) {
memset(BufLlc, 0xff, sizeof(BufLlc)); memset(BufLlc, 0xff, sizeof(BufLlc));
memset(BufSz, 0xff, sizeof(BufSz)); memset(BufSz, 0xff, sizeof(BufSz));
ArgNum = Subzero_ArgNum = i; ArgNum = i;
Buf = BufLlc;
Callee = Funcs[f].Callee; Callee = Funcs[f].Callee;
Funcs[f].Caller(); Funcs[f].Caller();
Buf = BufSz;
Callee = Funcs[f].Subzero_Callee; Callee = Funcs[f].Subzero_Callee;
Funcs[f].Caller(); Funcs[f].Caller();
......
...@@ -31,12 +31,6 @@ int ArrayInitFull[] = {10, 20, 30, 40, 50}; ...@@ -31,12 +31,6 @@ int ArrayInitFull[] = {10, 20, 30, 40, 50};
const int ArrayConst[] = {-10, -20, -30}; const int ArrayConst[] = {-10, -20, -30};
static double ArrayDouble[10] = { 0.5, 1.5, 2.5, 3.5 }; static double ArrayDouble[10] = { 0.5, 1.5, 2.5, 3.5 };
#if 0
// TODO(kschimpf) Add this example once we know how to not mangle
// uninitialized, external globals (so that we can compare that
// the same, unmangled relocations are used). See comment in
// TargetGlobalInitX8632::lower in IceTargetLoweringX8632.cpp for
// details.
static struct { static struct {
int Array1[5]; int Array1[5];
uint8_t *Pointer1; uint8_t *Pointer1;
...@@ -56,7 +50,6 @@ static struct { ...@@ -56,7 +50,6 @@ static struct {
{ ExternName3, {1000, 1010, 1020}, ExternName2 }, { ExternName3, {1000, 1010, 1020}, ExternName2 },
ExternName5, ExternName5,
}; };
#endif
#define ARRAY(a) \ #define ARRAY(a) \
{ (uint8_t *)(a), sizeof(a) } { (uint8_t *)(a), sizeof(a) }
...@@ -74,7 +67,7 @@ struct { ...@@ -74,7 +67,7 @@ struct {
ARRAY(ArrayDouble), ARRAY(ArrayDouble),
{(uint8_t *)(ArrayInitPartial + 2), {(uint8_t *)(ArrayInitPartial + 2),
sizeof(ArrayInitPartial) - 2 * sizeof(int)}, sizeof(ArrayInitPartial) - 2 * sizeof(int)},
// { (uint8_t*)(&StructEx), sizeof(StructEx) }, { (uint8_t*)(&StructEx), sizeof(StructEx) },
}; };
size_t NumArraysElements = sizeof(Arrays) / sizeof(*Arrays); size_t NumArraysElements = sizeof(Arrays) / sizeof(*Arrays);
......
...@@ -349,7 +349,7 @@ void Cfg::dump(const IceString &Message) { ...@@ -349,7 +349,7 @@ void Cfg::dump(const IceString &Message) {
Str << "define "; Str << "define ";
if (getInternal()) if (getInternal())
Str << "internal "; Str << "internal ";
Str << ReturnType << " @" << getFunctionName() << "("; Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "(";
for (SizeT i = 0; i < Args.size(); ++i) { for (SizeT i = 0; i < Args.size(); ++i) {
if (i > 0) if (i > 0)
Str << ", "; Str << ", ";
......
...@@ -114,8 +114,11 @@ public: ...@@ -114,8 +114,11 @@ public:
// global initializers. // global initializers.
Ice::Constant *convertConstant(const Constant *Const) { Ice::Constant *convertConstant(const Constant *Const) {
if (const auto GV = dyn_cast<GlobalValue>(Const)) { if (const auto GV = dyn_cast<GlobalValue>(Const)) {
return Ctx->getConstantSym(convertToIceType(GV->getType()), 0, Ice::GlobalDeclaration *Decl = getConverter().getGlobalDeclaration(GV);
GV->getName()); const Ice::RelocOffsetT Offset = 0;
return Ctx->getConstantSym(TypeConverter.getIcePointerType(),
Offset, Decl->getName(),
Decl->getSuppressMangling());
} else if (const auto CI = dyn_cast<ConstantInt>(Const)) { } else if (const auto CI = dyn_cast<ConstantInt>(Const)) {
Ice::Type Ty = convertToIceType(CI->getType()); Ice::Type Ty = convertToIceType(CI->getType());
if (Ty == Ice::IceType_i64) { if (Ty == Ice::IceType_i64) {
...@@ -690,21 +693,30 @@ void LLVM2ICEGlobalsConverter::convertGlobalsToIce( ...@@ -690,21 +693,30 @@ void LLVM2ICEGlobalsConverter::convertGlobalsToIce(
for (Module::const_global_iterator I = Mod->global_begin(), for (Module::const_global_iterator I = Mod->global_begin(),
E = Mod->global_end(); E = Mod->global_end();
I != E; ++I) { I != E; ++I) {
if (!I->hasInitializer() && Ctx->getFlags().AllowUninitializedGlobals)
continue;
const GlobalVariable *GV = I; const GlobalVariable *GV = I;
Ice::IceString Name = GV->getName();
if (!GV->hasInternalLinkage()) { Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV);
Ice::VariableDeclaration* VarDecl = cast<Ice::VariableDeclaration>(Var);
VariableDeclarations.push_back(VarDecl);
if (!GV->hasInternalLinkage() && GV->hasInitializer()) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Can't define external global declaration: " << Name; StrBuf << "Can't define external global declaration: " << GV->getName();
report_fatal_error(StrBuf.str()); report_fatal_error(StrBuf.str());
} }
Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV); if (!GV->hasInitializer()) {
Ice::VariableDeclaration* VarDecl = cast<Ice::VariableDeclaration>(Var); if (Ctx->getFlags().AllowUninitializedGlobals)
VariableDeclarations.push_back(VarDecl); continue;
else {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Global declaration missing initializer: " << GV->getName();
report_fatal_error(StrBuf.str());
}
}
const Constant *Initializer = GV->getInitializer(); const Constant *Initializer = GV->getInitializer();
if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) { if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) {
...@@ -858,9 +870,7 @@ void Converter::installGlobalDeclarations(Module *Mod) { ...@@ -858,9 +870,7 @@ void Converter::installGlobalDeclarations(Module *Mod) {
Var->setName(GV->getName()); Var->setName(GV->getName());
Var->setAlignment(GV->getAlignment()); Var->setAlignment(GV->getAlignment());
Var->setIsConstant(GV->isConstant()); Var->setIsConstant(GV->isConstant());
// Note: We allow external for cross tests. Var->setLinkage(GV->getLinkage());
// TODO(kschimpf) Put behind flag AllowUninitializedGlobals.
Var->setIsInternal(!GV->isExternallyInitialized());
GlobalDeclarationMap[GV] = Var; GlobalDeclarationMap[GV] = Var;
} }
} }
......
...@@ -68,12 +68,13 @@ void FunctionDeclaration::dumpType(Ostream &Stream) const { ...@@ -68,12 +68,13 @@ void FunctionDeclaration::dumpType(Ostream &Stream) const {
Stream << Signature; Stream << Signature;
} }
void FunctionDeclaration::dump(Ostream &Stream) const { void FunctionDeclaration::dump(GlobalContext *Ctx, Ostream &Stream) const {
if (IsProto) if (IsProto)
Stream << "declare "; Stream << "declare ";
::dumpLinkage(Stream, Linkage); ::dumpLinkage(Stream, Linkage);
::dumpCallingConv(Stream, CallingConv); ::dumpCallingConv(Stream, CallingConv);
Stream << Signature.getReturnType() << " @" << Name << "("; Stream << Signature.getReturnType() << " @"
<< (Ctx ? Ctx->mangleName(Name) : Name) << "(";
bool IsFirst = true; bool IsFirst = true;
for (Type ArgTy : Signature.getArgList()) { for (Type ArgTy : Signature.getArgList()) {
if (IsFirst) if (IsFirst)
...@@ -111,9 +112,11 @@ void VariableDeclaration::dumpType(Ostream &Stream) const { ...@@ -111,9 +112,11 @@ void VariableDeclaration::dumpType(Ostream &Stream) const {
} }
} }
void VariableDeclaration::dump(Ostream &Stream) const { void VariableDeclaration::dump(GlobalContext *Ctx, Ostream &Stream) const {
Stream << "@" << Name << " = internal " Stream << "@" << ((Ctx && !getSuppressMangling())
<< (IsConstant ? "constant" : "global") << " "; ? Ctx->mangleName(Name) : Name) << " = ";
::dumpLinkage(Stream, Linkage);
Stream << " " << (IsConstant ? "constant" : "global") << " ";
// Add initializer. // Add initializer.
if (Initializers.size() == 1) { if (Initializers.size() == 1) {
...@@ -128,7 +131,7 @@ void VariableDeclaration::dump(Ostream &Stream) const { ...@@ -128,7 +131,7 @@ void VariableDeclaration::dump(Ostream &Stream) const {
} else { } else {
Stream << ", "; Stream << ", ";
} }
Init->dump(Stream); Init->dump(Ctx, Stream);
} }
Stream << " }>"; Stream << " }>";
} }
...@@ -143,7 +146,8 @@ void VariableDeclaration::Initializer::dumpType(Ostream &Stream) const { ...@@ -143,7 +146,8 @@ void VariableDeclaration::Initializer::dumpType(Ostream &Stream) const {
Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]"; Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]";
} }
void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const { void VariableDeclaration::DataInitializer::dump(
GlobalContext *, 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
...@@ -158,7 +162,8 @@ void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const { ...@@ -158,7 +162,8 @@ void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const {
Stream << "\""; Stream << "\"";
} }
void VariableDeclaration::ZeroInitializer::dump(Ostream &Stream) const { void VariableDeclaration::ZeroInitializer::dump(
GlobalContext *, Ostream &Stream) const {
dumpType(Stream); dumpType(Stream);
Stream << " zeroinitializer"; Stream << " zeroinitializer";
} }
...@@ -167,7 +172,8 @@ void VariableDeclaration::RelocInitializer::dumpType(Ostream &Stream) const { ...@@ -167,7 +172,8 @@ void VariableDeclaration::RelocInitializer::dumpType(Ostream &Stream) const {
Stream << Ice::IceType_i32; Stream << Ice::IceType_i32;
} }
void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const { void VariableDeclaration::RelocInitializer::dump(
GlobalContext *Ctx, Ostream &Stream) const {
if (Offset != 0) { if (Offset != 0) {
dumpType(Stream); dumpType(Stream);
Stream << " add ("; Stream << " add (";
...@@ -175,7 +181,12 @@ void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const { ...@@ -175,7 +181,12 @@ void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const {
dumpType(Stream); dumpType(Stream);
Stream << " ptrtoint ("; Stream << " ptrtoint (";
Declaration->dumpType(Stream); Declaration->dumpType(Stream);
Stream << "* @" << Declaration->getName() << " to "; Stream << "* @";
if (Ctx)
Stream << Ctx->mangleName(Declaration->getName());
else
Stream << Declaration->getName();
Stream << " to ";
dumpType(Stream); dumpType(Stream);
Stream << ")"; Stream << ")";
if (Offset != 0) { if (Offset != 0) {
......
...@@ -43,26 +43,45 @@ public: ...@@ -43,26 +43,45 @@ public:
const IceString &getName() const { return Name; } const IceString &getName() const { return Name; }
void setName(const IceString &NewName) { Name = NewName; } void setName(const IceString &NewName) { Name = NewName; }
bool hasName() const { return !Name.empty(); } bool hasName() const { return !Name.empty(); }
bool isInternal() const {
return Linkage == llvm::GlobalValue::InternalLinkage;
}
llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; }
bool isExternal() const {
return Linkage == llvm::GlobalValue::ExternalLinkage;
}
void setLinkage(llvm::GlobalValue::LinkageTypes NewLinkage) {
Linkage = NewLinkage;
}
virtual ~GlobalDeclaration() {} virtual ~GlobalDeclaration() {}
/// Returns true if the declaration is external.
virtual bool getIsExternal() const = 0;
/// Prints out type of the global declaration. /// Prints out type of the global declaration.
virtual void dumpType(Ostream &Stream) const = 0; virtual void dumpType(Ostream &Stream) const = 0;
/// Prints out the global declaration. /// Prints out the global declaration.
virtual void dump(Ostream &Stream) const = 0; virtual void dump(GlobalContext *Ctx, Ostream &Stream) const = 0;
void dump(Ostream &Stream) const {
GlobalContext *const Ctx = nullptr;
dump(Ctx, Stream);
}
/// Returns true if when emitting names, we should suppress mangling.
virtual bool getSuppressMangling() const = 0;
// Mangles name for cross tests, unless external and not defined locally // Mangles name for cross tests, unless external and not defined locally
// (so that relocations accross llvm2ice and pnacl-llc will work). // (so that relocations accross llvm2ice and pnacl-llc will work).
virtual IceString mangleName(GlobalContext *Ctx) const = 0; virtual IceString mangleName(GlobalContext *Ctx) const {
return getSuppressMangling() ? Name : Ctx->mangleName(Name);
}
protected: protected:
GlobalDeclaration(GlobalDeclarationKind Kind) : Kind(Kind) {} GlobalDeclaration(GlobalDeclarationKind Kind,
llvm::GlobalValue::LinkageTypes Linkage)
: Kind(Kind), Linkage(Linkage) {}
const GlobalDeclarationKind Kind; const GlobalDeclarationKind Kind;
IceString Name; IceString Name;
llvm::GlobalValue::LinkageTypes Linkage;
}; };
// Models a function declaration. This includes the type signature of // Models a function declaration. This includes the type signature of
...@@ -81,33 +100,27 @@ public: ...@@ -81,33 +100,27 @@ public:
~FunctionDeclaration() final {} ~FunctionDeclaration() final {}
const FuncSigType &getSignature() const { return Signature; } const FuncSigType &getSignature() const { return Signature; }
llvm::CallingConv::ID getCallingConv() const { return CallingConv; } llvm::CallingConv::ID getCallingConv() const { return CallingConv; }
llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; }
// isProto implies that there isn't a (local) definition for the function. // isProto implies that there isn't a (local) definition for the function.
bool isProto() const { return IsProto; } bool isProto() const { return IsProto; }
static bool classof(const GlobalDeclaration *Addr) { static bool classof(const GlobalDeclaration *Addr) {
return Addr->getKind() == FunctionDeclarationKind; return Addr->getKind() == FunctionDeclarationKind;
} }
void dumpType(Ostream &Stream) const final; void dumpType(Ostream &Stream) const final;
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
bool getIsExternal() const final { bool getSuppressMangling() const final {
return Linkage == llvm::GlobalValue::ExternalLinkage; return isExternal() && IsProto;
}
virtual IceString mangleName(GlobalContext *Ctx) const final {
return (getIsExternal() && IsProto) ? Name : Ctx->mangleName(Name);
} }
private: private:
const Ice::FuncSigType Signature; const Ice::FuncSigType Signature;
llvm::CallingConv::ID CallingConv; llvm::CallingConv::ID CallingConv;
llvm::GlobalValue::LinkageTypes Linkage;
bool IsProto; bool IsProto;
FunctionDeclaration(const FuncSigType &Signature, FunctionDeclaration(const FuncSigType &Signature,
llvm::CallingConv::ID CallingConv, llvm::CallingConv::ID CallingConv,
llvm::GlobalValue::LinkageTypes Linkage, bool IsProto) llvm::GlobalValue::LinkageTypes Linkage, bool IsProto)
: GlobalDeclaration(FunctionDeclarationKind), Signature(Signature), : GlobalDeclaration(FunctionDeclarationKind, Linkage),
CallingConv(CallingConv), Linkage(Linkage), IsProto(IsProto) {} Signature(Signature), CallingConv(CallingConv), IsProto(IsProto) {}
}; };
/// Models a global variable declaration, and its initializers. /// Models a global variable declaration, and its initializers.
...@@ -134,7 +147,10 @@ public: ...@@ -134,7 +147,10 @@ public:
InitializerKind getKind() const { return Kind; } InitializerKind getKind() const { return Kind; }
virtual ~Initializer() {} virtual ~Initializer() {}
virtual SizeT getNumBytes() const = 0; virtual SizeT getNumBytes() const = 0;
virtual void dump(Ostream &Stream) const = 0; virtual void dump(GlobalContext *Ctx, Ostream &Stream) const = 0;
void dump(Ostream &Stream) const {
dump(nullptr, Stream);
}
virtual void dumpType(Ostream &Stream) const; virtual void dumpType(Ostream &Stream) const;
protected: protected:
...@@ -170,7 +186,7 @@ public: ...@@ -170,7 +186,7 @@ public:
~DataInitializer() override {} ~DataInitializer() override {}
const DataVecType &getContents() const { return Contents; } const DataVecType &getContents() const { return Contents; }
SizeT getNumBytes() const final { return Contents.size(); } SizeT getNumBytes() const final { return Contents.size(); }
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
static bool classof(const Initializer *D) { static bool classof(const Initializer *D) {
return D->getKind() == DataInitializerKind; return D->getKind() == DataInitializerKind;
} }
...@@ -190,7 +206,7 @@ public: ...@@ -190,7 +206,7 @@ public:
: Initializer(ZeroInitializerKind), Size(Size) {} : Initializer(ZeroInitializerKind), Size(Size) {}
~ZeroInitializer() override {} ~ZeroInitializer() override {}
SizeT getNumBytes() const final { return Size; } SizeT getNumBytes() const final { return Size; }
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
static bool classof(const Initializer *Z) { static bool classof(const Initializer *Z) {
return Z->getKind() == ZeroInitializerKind; return Z->getKind() == ZeroInitializerKind;
} }
...@@ -218,7 +234,7 @@ public: ...@@ -218,7 +234,7 @@ public:
RelocOffsetType getOffset() const { return Offset; } RelocOffsetType getOffset() const { return Offset; }
const GlobalDeclaration *getDeclaration() const { return Declaration; } const GlobalDeclaration *getDeclaration() const { return Declaration; }
SizeT getNumBytes() const final { return RelocAddrSize; } SizeT getNumBytes() const final { return RelocAddrSize; }
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
void dumpType(Ostream &Stream) const final; void dumpType(Ostream &Stream) const final;
static bool classof(const Initializer *R) { static bool classof(const Initializer *R) {
return R->getKind() == RelocInitializerKind; return R->getKind() == RelocInitializerKind;
...@@ -242,10 +258,8 @@ public: ...@@ -242,10 +258,8 @@ public:
void setIsConstant(bool NewValue) { IsConstant = NewValue; } void setIsConstant(bool NewValue) { IsConstant = NewValue; }
uint32_t getAlignment() const { return Alignment; } uint32_t getAlignment() const { return Alignment; }
void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; }
bool getIsInternal() const { return IsInternal; } bool hasInitializer() const { return !Initializers.empty(); }
void setIsInternal(bool NewValue) { IsInternal = NewValue; } bool hasNonzeroInitializer() const {
bool getIsExternal() const final { return !getIsInternal(); }
bool hasInitializer() const {
return !(Initializers.size() == 1 && return !(Initializers.size() == 1 &&
llvm::isa<ZeroInitializer>(Initializers[0])); llvm::isa<ZeroInitializer>(Initializers[0]));
} }
...@@ -272,18 +286,16 @@ public: ...@@ -272,18 +286,16 @@ public:
/// Prints out the definition of the global variable declaration /// Prints out the definition of the global variable declaration
/// (including initialization). /// (including initialization).
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
static bool classof(const GlobalDeclaration *Addr) { static bool classof(const GlobalDeclaration *Addr) {
return Addr->getKind() == VariableDeclarationKind; return Addr->getKind() == VariableDeclarationKind;
} }
IceString mangleName(GlobalContext *Ctx) const final { bool getSuppressMangling() const final {
return (getIsExternal() && !hasInitializer()) return isExternal() && !hasInitializer();
? Name : Ctx->mangleName(Name);
} }
private: private:
// list of initializers for the declared variable. // list of initializers for the declared variable.
InitializerListType Initializers; InitializerListType Initializers;
...@@ -291,12 +303,11 @@ private: ...@@ -291,12 +303,11 @@ private:
uint32_t Alignment; uint32_t Alignment;
// True if a declared (global) constant. // True if a declared (global) constant.
bool IsConstant; bool IsConstant;
// True if the declaration is internal.
bool IsInternal;
VariableDeclaration() VariableDeclaration()
: GlobalDeclaration(VariableDeclarationKind), Alignment(0), : GlobalDeclaration(VariableDeclarationKind,
IsConstant(false), IsInternal(true) {} llvm::GlobalValue::InternalLinkage),
Alignment(0), IsConstant(false) {}
}; };
template <class StreamType> template <class StreamType>
......
...@@ -460,8 +460,13 @@ void ConstantRelocatable::emit(GlobalContext *Ctx) const { ...@@ -460,8 +460,13 @@ void ConstantRelocatable::emit(GlobalContext *Ctx) const {
} }
} }
void ConstantRelocatable::dump(const Cfg *, Ostream &Str) const { void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const {
Str << "@" << Name; Str << "@";
if (Func && !SuppressMangling) {
Str << Func->getContext()->mangleName(Name);
} else {
Str << Name;
}
if (Offset) if (Offset)
Str << "+" << Offset; Str << "+" << Offset;
} }
......
...@@ -4448,10 +4448,14 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) { ...@@ -4448,10 +4448,14 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
const VariableDeclaration::InitializerListType &Initializers = const VariableDeclaration::InitializerListType &Initializers =
Var.getInitializers(); Var.getInitializers();
assert(Initializers.size());
bool HasInitializer = Var.hasInitializer(); // If external and not initialized, this must be a cross test.
// Don't generate a declaration for such cases.
bool IsExternal = Var.isExternal();
if (IsExternal && !Var.hasInitializer()) return;
bool HasNonzeroInitializer = Var.hasNonzeroInitializer();
bool IsConstant = Var.getIsConstant(); bool IsConstant = Var.getIsConstant();
bool IsExternal = Var.getIsExternal();
uint32_t Align = Var.getAlignment(); uint32_t Align = Var.getAlignment();
SizeT Size = Var.getNumBytes(); SizeT Size = Var.getNumBytes();
IceString MangledName = Var.mangleName(Ctx); IceString MangledName = Var.mangleName(Ctx);
...@@ -4463,7 +4467,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) { ...@@ -4463,7 +4467,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
if (IsConstant) if (IsConstant)
Str << "\t.section\t.rodata" << SectionSuffix << ",\"a\",@progbits\n"; Str << "\t.section\t.rodata" << SectionSuffix << ",\"a\",@progbits\n";
else if (HasInitializer) else if (HasNonzeroInitializer)
Str << "\t.section\t.data" << SectionSuffix << ",\"aw\",@progbits\n"; Str << "\t.section\t.data" << SectionSuffix << ",\"aw\",@progbits\n";
else if (IsExternal) else if (IsExternal)
Str << "\t.section\t.bss" << SectionSuffix << ",\"aw\",@nobits\n"; Str << "\t.section\t.bss" << SectionSuffix << ",\"aw\",@nobits\n";
...@@ -4471,20 +4475,20 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) { ...@@ -4471,20 +4475,20 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
if (IsExternal) if (IsExternal)
Str << "\t.globl\t" << MangledName << "\n"; Str << "\t.globl\t" << MangledName << "\n";
else if (!IsConstant && !HasInitializer) else if (!IsConstant && !HasNonzeroInitializer)
Str << "\t.local\t" << MangledName << "\n"; Str << "\t.local\t" << MangledName << "\n";
// Internal symbols only get .local when using .comm. // Internal symbols only get .local when using .comm.
if ((IsConstant || HasInitializer || IsExternal) && Align > 1) if ((IsConstant || HasNonzeroInitializer || IsExternal) && Align > 1)
Str << "\t.align\t" << Align << "\n"; Str << "\t.align\t" << Align << "\n";
// Alignment is part of .comm. // Alignment is part of .comm.
if (IsConstant || HasInitializer || IsExternal) if (IsConstant || HasNonzeroInitializer || IsExternal)
Str << MangledName << ":\n"; Str << MangledName << ":\n";
else else
Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n"; Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n";
if (HasInitializer) { if (HasNonzeroInitializer) {
for (VariableDeclaration::Initializer *Init : Initializers) { for (VariableDeclaration::Initializer *Init : Initializers) {
switch (Init->getKind()) { switch (Init->getKind()) {
case VariableDeclaration::Initializer::DataInitializerKind: { case VariableDeclaration::Initializer::DataInitializerKind: {
...@@ -4526,7 +4530,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) { ...@@ -4526,7 +4530,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
Str << "\t.zero\t" << Size << "\n"; Str << "\t.zero\t" << Size << "\n";
// Size is part of .comm. // Size is part of .comm.
if (IsConstant || HasInitializer || IsExternal) if (IsConstant || HasNonzeroInitializer || IsExternal)
Str << "\t.size\t" << MangledName << ", " << Size << "\n"; Str << "\t.size\t" << MangledName << ", " << Size << "\n";
// Size is part of .comm. // Size is part of .comm.
} }
......
...@@ -88,7 +88,7 @@ void Translator::lowerGlobals( ...@@ -88,7 +88,7 @@ void Translator::lowerGlobals(
Ostream &Stream = Ctx->getStrDump(); Ostream &Stream = Ctx->getStrDump();
for (const Ice::VariableDeclaration *Global : VariableDeclarations) { for (const Ice::VariableDeclaration *Global : VariableDeclarations) {
if (DumpGlobalVariables) if (DumpGlobalVariables)
Global->dump(Stream); Global->dump(getContext(), Stream);
if(!DisableTranslation) if(!DisableTranslation)
GlobalLowering->lower(*Global); GlobalLowering->lower(*Global);
} }
......
...@@ -286,22 +286,30 @@ public: ...@@ -286,22 +286,30 @@ public:
// If reached, no such constant exists, create one. // If reached, no such constant exists, create one.
// TODO(kschimpf) Don't get addresses of intrinsic function declarations. // TODO(kschimpf) Don't get addresses of intrinsic function declarations.
std::string Name; Ice::GlobalDeclaration *Decl = nullptr;
unsigned FcnIDSize = FunctionDeclarationList.size(); unsigned FcnIDSize = FunctionDeclarationList.size();
if (ID < FcnIDSize) { if (ID < FcnIDSize) {
Name = FunctionDeclarationList[ID]->getName(); Decl = FunctionDeclarationList[ID];
} else if ((ID - FcnIDSize) < VariableDeclarations.size()) { } else if ((ID - FcnIDSize) < VariableDeclarations.size()) {
Name = VariableDeclarations[ID - FcnIDSize]->getName(); Decl = VariableDeclarations[ID - FcnIDSize];
}
std::string Name;
bool SuppressMangling;
if (Decl) {
Name = Decl->getName();
SuppressMangling = Decl->getSuppressMangling();
} else { } else {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Reference to global not defined: " << ID; StrBuf << "Reference to global not defined: " << ID;
Error(StrBuf.str()); Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Name = "??"; Name = "??";
SuppressMangling = false;
} }
const Ice::RelocOffsetT Offset = 0; const Ice::RelocOffsetT Offset = 0;
C = getTranslator().getContext()->getConstantSym( C = getTranslator().getContext()->getConstantSym(
getIcePointerType(), Offset, Name); getIcePointerType(), Offset, Name, SuppressMangling);
ValueIDConstants[ID] = C; ValueIDConstants[ID] = C;
return C; return C;
} }
......
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