Commit 989a703f by Jim Stichnoth

Subzero: Add the "llvm2ice -ffunction-sections" argument.

The purpose is to enable bisection debugging of Subzero-translated functions, using objcopy to selectively splice functions from llc and Subzero into the binary. Note that llvm-mc claims to take this argument, but actually does nothing with it, so we need to implement it in Subzero. Also moves the ClFlags object into the GlobalContext so everyone can access it. BUG= none R=wala@chromium.org Review URL: https://codereview.chromium.org/455633002
parent 51e8cfba
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "IceCfg.h" #include "IceCfg.h"
#include "IceCfgNode.h" #include "IceCfgNode.h"
#include "IceClFlags.h"
#include "IceDefs.h" #include "IceDefs.h"
#include "IceInst.h" #include "IceInst.h"
#include "IceLiveness.h" #include "IceLiveness.h"
...@@ -300,8 +301,10 @@ void Cfg::emit() { ...@@ -300,8 +301,10 @@ void Cfg::emit() {
<< "\n\n"; << "\n\n";
} }
Str << "\t.text\n"; Str << "\t.text\n";
if (!getInternal()) {
IceString MangledName = getContext()->mangleName(getFunctionName()); IceString MangledName = getContext()->mangleName(getFunctionName());
if (Ctx->getFlags().FunctionSections)
Str << "\t.section\t.text." << MangledName << "\n";
if (!getInternal()) {
Str << "\t.globl\t" << MangledName << "\n"; Str << "\t.globl\t" << MangledName << "\n";
Str << "\t.type\t" << MangledName << ",@function\n"; Str << "\t.type\t" << MangledName << ",@function\n";
} }
......
...@@ -20,12 +20,15 @@ class ClFlags { ...@@ -20,12 +20,15 @@ class ClFlags {
public: public:
ClFlags() ClFlags()
: DisableInternal(false), SubzeroTimingEnabled(false), : DisableInternal(false), SubzeroTimingEnabled(false),
DisableTranslation(false), DisableGlobals(false) {} DisableTranslation(false), DisableGlobals(false),
FunctionSections(false) {}
bool DisableInternal; bool DisableInternal;
bool SubzeroTimingEnabled; bool SubzeroTimingEnabled;
bool DisableTranslation; bool DisableTranslation;
bool DisableGlobals; bool DisableGlobals;
bool FunctionSections;
}; };
}
} // end of namespace Ice
#endif // SUBZERO_SRC_ICECLFLAGS_H #endif // SUBZERO_SRC_ICECLFLAGS_H
...@@ -676,12 +676,12 @@ private: ...@@ -676,12 +676,12 @@ private:
std::map<const BasicBlock *, Ice::CfgNode *> NodeMap; std::map<const BasicBlock *, Ice::CfgNode *> NodeMap;
}; };
} // end of anonymous namespace. } // end of anonymous namespace
namespace Ice { namespace Ice {
void Converter::convertToIce(Module *Mod) { void Converter::convertToIce(Module *Mod) {
if (!Flags.DisableGlobals) if (!Ctx->getFlags().DisableGlobals)
convertGlobals(Mod); convertGlobals(Mod);
convertFunctions(Mod); convertFunctions(Mod);
} }
...@@ -723,7 +723,8 @@ void Converter::convertGlobals(Module *Mod) { ...@@ -723,7 +723,8 @@ void Converter::convertGlobals(Module *Mod) {
} }
GlobalLowering->lower(Name, Align, IsInternal, IsConst, IsZeroInitializer, GlobalLowering->lower(Name, Align, IsInternal, IsConst, IsZeroInitializer,
NumElements, Data, Flags.DisableTranslation); NumElements, Data,
Ctx->getFlags().DisableTranslation);
} }
GlobalLowering.reset(); GlobalLowering.reset();
} }
...@@ -736,7 +737,7 @@ void Converter::convertFunctions(Module *Mod) { ...@@ -736,7 +737,7 @@ void Converter::convertFunctions(Module *Mod) {
Timer TConvert; Timer TConvert;
Cfg *Fcn = FunctionConverter.convertFunction(I); Cfg *Fcn = FunctionConverter.convertFunction(I);
if (Flags.SubzeroTimingEnabled) { if (Ctx->getFlags().SubzeroTimingEnabled) {
std::cerr << "[Subzero timing] Convert function " std::cerr << "[Subzero timing] Convert function "
<< Fcn->getFunctionName() << ": " << TConvert.getElapsedSec() << Fcn->getFunctionName() << ": " << TConvert.getElapsedSec()
<< " sec\n"; << " sec\n";
...@@ -747,4 +748,4 @@ void Converter::convertFunctions(Module *Mod) { ...@@ -747,4 +748,4 @@ void Converter::convertFunctions(Module *Mod) {
emitConstants(); emitConstants();
} }
} // end of Ice namespace. } // end of namespace Ice
...@@ -24,7 +24,7 @@ namespace Ice { ...@@ -24,7 +24,7 @@ namespace Ice {
class Converter : public Translator { class Converter : public Translator {
public: public:
Converter(GlobalContext *Ctx, Ice::ClFlags &Flags) : Translator(Ctx, Flags) {} Converter(GlobalContext *Ctx) : Translator(Ctx) {}
/// 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(llvm::Module *Mod); void convertToIce(llvm::Module *Mod);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "IceDefs.h" #include "IceDefs.h"
#include "IceTypes.h" #include "IceTypes.h"
#include "IceCfg.h" #include "IceCfg.h"
#include "IceClFlags.h"
#include "IceGlobalContext.h" #include "IceGlobalContext.h"
#include "IceOperand.h" #include "IceOperand.h"
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
...@@ -116,10 +117,10 @@ public: ...@@ -116,10 +117,10 @@ public:
GlobalContext::GlobalContext(llvm::raw_ostream *OsDump, GlobalContext::GlobalContext(llvm::raw_ostream *OsDump,
llvm::raw_ostream *OsEmit, VerboseMask Mask, llvm::raw_ostream *OsEmit, VerboseMask Mask,
TargetArch Arch, OptLevel Opt, TargetArch Arch, OptLevel Opt,
IceString TestPrefix) IceString TestPrefix, const ClFlags &Flags)
: StrDump(OsDump), StrEmit(OsEmit), VMask(Mask), : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask),
ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt), ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt),
TestPrefix(TestPrefix), HasEmittedFirstMethod(false) {} TestPrefix(TestPrefix), Flags(Flags), HasEmittedFirstMethod(false) {}
// Scan a string for S[0-9A-Z]*_ patterns and replace them with // Scan a string for S[0-9A-Z]*_ patterns and replace them with
// S<num>_ where <num> is the next base-36 value. If a type name // S<num>_ where <num> is the next base-36 value. If a type name
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
namespace Ice { namespace Ice {
class ClFlags;
// TODO: Accesses to all non-const fields of GlobalContext need to // TODO: Accesses to all non-const fields of GlobalContext need to
// be synchronized, especially the constant pool, the allocator, and // be synchronized, especially the constant pool, the allocator, and
// the output streams. // the output streams.
...@@ -32,7 +34,7 @@ class GlobalContext { ...@@ -32,7 +34,7 @@ class GlobalContext {
public: public:
GlobalContext(llvm::raw_ostream *OsDump, llvm::raw_ostream *OsEmit, GlobalContext(llvm::raw_ostream *OsDump, llvm::raw_ostream *OsEmit,
VerboseMask Mask, TargetArch Arch, OptLevel Opt, VerboseMask Mask, TargetArch Arch, OptLevel Opt,
IceString TestPrefix); IceString TestPrefix, const ClFlags &Flags);
~GlobalContext(); ~GlobalContext();
// Returns true if any of the specified options in the verbose mask // Returns true if any of the specified options in the verbose mask
...@@ -86,6 +88,8 @@ public: ...@@ -86,6 +88,8 @@ public:
// constants of a given type. // constants of a given type.
ConstantList getConstantPool(Type Ty) const; ConstantList getConstantPool(Type Ty) const;
const ClFlags &getFlags() const { return Flags; }
// Allocate data of type T using the global allocator. // Allocate data of type T using the global allocator.
template <typename T> T *allocate() { return Allocator.Allocate<T>(); } template <typename T> T *allocate() { return Allocator.Allocate<T>(); }
...@@ -102,6 +106,7 @@ private: ...@@ -102,6 +106,7 @@ private:
const TargetArch Arch; const TargetArch Arch;
const OptLevel Opt; const OptLevel Opt;
const IceString TestPrefix; const IceString TestPrefix;
const ClFlags &Flags;
bool HasEmittedFirstMethod; bool HasEmittedFirstMethod;
GlobalContext(const GlobalContext &) LLVM_DELETED_FUNCTION; GlobalContext(const GlobalContext &) LLVM_DELETED_FUNCTION;
GlobalContext &operator=(const GlobalContext &) LLVM_DELETED_FUNCTION; GlobalContext &operator=(const GlobalContext &) LLVM_DELETED_FUNCTION;
......
...@@ -179,7 +179,7 @@ const struct IceIntrinsicsEntry_ { ...@@ -179,7 +179,7 @@ const struct IceIntrinsicsEntry_ {
}; };
const size_t IceIntrinsicsTableSize = llvm::array_lengthof(IceIntrinsicsTable); const size_t IceIntrinsicsTableSize = llvm::array_lengthof(IceIntrinsicsTable);
} // end of namespace } // end of anonymous namespace
Intrinsics::Intrinsics() { Intrinsics::Intrinsics() {
for (size_t I = 0; I < IceIntrinsicsTableSize; ++I) { for (size_t I = 0; I < IceIntrinsicsTableSize; ++I) {
......
...@@ -26,14 +26,14 @@ Translator::~Translator() {} ...@@ -26,14 +26,14 @@ Translator::~Translator() {}
void Translator::translateFcn(Ice::Cfg *Fcn) { void Translator::translateFcn(Ice::Cfg *Fcn) {
Func.reset(Fcn); Func.reset(Fcn);
if (Flags.DisableInternal) if (Ctx->getFlags().DisableInternal)
Func->setInternal(false); Func->setInternal(false);
if (Flags.DisableTranslation) { if (Ctx->getFlags().DisableTranslation) {
Func->dump(); Func->dump();
} else { } else {
Ice::Timer TTranslate; Ice::Timer TTranslate;
Func->translate(); Func->translate();
if (Flags.SubzeroTimingEnabled) { if (Ctx->getFlags().SubzeroTimingEnabled) {
std::cerr << "[Subzero timing] Translate function " std::cerr << "[Subzero timing] Translate function "
<< Func->getFunctionName() << ": " << TTranslate.getElapsedSec() << Func->getFunctionName() << ": " << TTranslate.getElapsedSec()
<< " sec\n"; << " sec\n";
...@@ -45,7 +45,7 @@ void Translator::translateFcn(Ice::Cfg *Fcn) { ...@@ -45,7 +45,7 @@ void Translator::translateFcn(Ice::Cfg *Fcn) {
Ice::Timer TEmit; Ice::Timer TEmit;
Func->emit(); Func->emit();
if (Flags.SubzeroTimingEnabled) { if (Ctx->getFlags().SubzeroTimingEnabled) {
std::cerr << "[Subzero timing] Emit function " << Func->getFunctionName() std::cerr << "[Subzero timing] Emit function " << Func->getFunctionName()
<< ": " << TEmit.getElapsedSec() << " sec\n"; << ": " << TEmit.getElapsedSec() << " sec\n";
} }
...@@ -53,6 +53,6 @@ void Translator::translateFcn(Ice::Cfg *Fcn) { ...@@ -53,6 +53,6 @@ void Translator::translateFcn(Ice::Cfg *Fcn) {
} }
void Translator::emitConstants() { void Translator::emitConstants() {
if (!Flags.DisableTranslation && Func) if (!Ctx->getFlags().DisableTranslation && Func)
Func->getTarget()->emitConstants(); Func->getTarget()->emitConstants();
} }
...@@ -29,15 +29,13 @@ class GlobalContext; ...@@ -29,15 +29,13 @@ class GlobalContext;
// machine instructions. // machine instructions.
class Translator { class Translator {
public: public:
Translator(GlobalContext *Ctx, ClFlags &Flags) Translator(GlobalContext *Ctx) : Ctx(Ctx), ErrorStatus(0) {}
: Ctx(Ctx), Flags(Flags), ErrorStatus(0) {}
~Translator(); ~Translator();
bool getErrorStatus() const { return ErrorStatus; } bool getErrorStatus() const { return ErrorStatus; }
protected: protected:
GlobalContext *Ctx; GlobalContext *Ctx;
ClFlags &Flags;
// The exit status of the translation. False is successful. True // The exit status of the translation. False is successful. True
// otherwise. // otherwise.
bool ErrorStatus; bool ErrorStatus;
......
...@@ -801,7 +801,7 @@ bool TopLevelParser::ParseBlock(unsigned BlockID) { ...@@ -801,7 +801,7 @@ bool TopLevelParser::ParseBlock(unsigned BlockID) {
return Parser.ParseThisBlock(); return Parser.ParseThisBlock();
} }
} // end of anonymous namespace. } // end of anonymous namespace
namespace Ice { namespace Ice {
...@@ -856,4 +856,4 @@ void PNaClTranslator::translate(const std::string &IRFilename) { ...@@ -856,4 +856,4 @@ void PNaClTranslator::translate(const std::string &IRFilename) {
return; return;
} }
} // end of anonymous namespace. } // end of namespace Ice
...@@ -22,8 +22,7 @@ namespace Ice { ...@@ -22,8 +22,7 @@ namespace Ice {
class PNaClTranslator : public Translator { class PNaClTranslator : public Translator {
public: public:
PNaClTranslator(GlobalContext *Ctx, ClFlags &Flags) PNaClTranslator(GlobalContext *Ctx) : Translator(Ctx) {}
: Translator(Ctx, Flags) {}
// Reads the PNaCl bitcode file and translates to ICE, which is then // Reads the PNaCl bitcode file and translates to ICE, which is then
// converted to machine code. Sets ErrorStatus to true if any // converted to machine code. Sets ErrorStatus to true if any
// errors occurred. // errors occurred.
......
...@@ -59,6 +59,9 @@ static cl::opt<Ice::TargetArch> TargetArch( ...@@ -59,6 +59,9 @@ static cl::opt<Ice::TargetArch> TargetArch(
clEnumValN(Ice::Target_ARM32, "arm", "arm32"), clEnumValN(Ice::Target_ARM32, "arm", "arm32"),
clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"), clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"),
clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd)); clEnumValN(Ice::Target_ARM64, "arm64", "arm64"), clEnumValEnd));
static cl::opt<bool>
FunctionSections("ffunction-sections",
cl::desc("Emit functions into separate sections"));
static cl::opt<Ice::OptLevel> static cl::opt<Ice::OptLevel>
OptLevel(cl::desc("Optimization level"), cl::init(Ice::Opt_m1), OptLevel(cl::desc("Optimization level"), cl::init(Ice::Opt_m1),
cl::value_desc("level"), cl::value_desc("level"),
...@@ -126,16 +129,18 @@ int main(int argc, char **argv) { ...@@ -126,16 +129,18 @@ int main(int argc, char **argv) {
raw_os_ostream *Ls = new raw_os_ostream(LogFilename == "-" ? std::cout : Lfs); raw_os_ostream *Ls = new raw_os_ostream(LogFilename == "-" ? std::cout : Lfs);
Ls->SetUnbuffered(); Ls->SetUnbuffered();
Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix);
Ice::ClFlags Flags; Ice::ClFlags Flags;
Flags.DisableInternal = DisableInternal; Flags.DisableInternal = DisableInternal;
Flags.SubzeroTimingEnabled = SubzeroTimingEnabled; Flags.SubzeroTimingEnabled = SubzeroTimingEnabled;
Flags.DisableTranslation = DisableTranslation; Flags.DisableTranslation = DisableTranslation;
Flags.DisableGlobals = DisableGlobals; Flags.DisableGlobals = DisableGlobals;
Flags.FunctionSections = FunctionSections;
Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix,
Flags);
if (BuildOnRead) { if (BuildOnRead) {
Ice::PNaClTranslator Translator(&Ctx, Flags); Ice::PNaClTranslator Translator(&Ctx);
Translator.translate(IRFilename); Translator.translate(IRFilename);
return Translator.getErrorStatus(); return Translator.getErrorStatus();
} else { } else {
...@@ -155,7 +160,7 @@ int main(int argc, char **argv) { ...@@ -155,7 +160,7 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
Ice::Converter Converter(&Ctx, Flags); Ice::Converter Converter(&Ctx);
Converter.convertToIce(Mod); Converter.convertToIce(Mod);
return Converter.getErrorStatus(); return Converter.getErrorStatus();
} }
......
; Tests the Subzero "name mangling" when using the "llvm2ice --prefix" ; Tests the Subzero "name mangling" when using the "llvm2ice --prefix"
; option. ; option. Also does a quick smoke test of -ffunction-sections.
; RUN: %llvm2ice --verbose none %s | FileCheck %s ; RUN: %llvm2ice --verbose none -ffunction-sections %s | FileCheck %s
; TODO: The following line causes this test to fail. ; TODO: The following line causes this test to fail.
; RUIN: %llvm2ice --verbose none %s \ ; RUIN: %llvm2ice --verbose none %s \
; RUIN: | llvm-mc -arch=x86 -x86-asm-syntax=intel -filetype=obj ; RUIN: | llvm-mc -arch=x86 -x86-asm-syntax=intel -filetype=obj
; RUN: %llvm2ice --verbose none --prefix Subzero %s | FileCheck --check-prefix=MANGLE %s ; RUN: %llvm2ice --verbose none --prefix Subzero -ffunction-sections %s \
; RUN: | FileCheck --check-prefix=MANGLE %s
; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s ; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s
; RUN: %llvm2iceinsts %s | %szdiff %s | FileCheck --check-prefix=DUMP %s ; RUN: %llvm2iceinsts %s | %szdiff %s | FileCheck --check-prefix=DUMP %s
; RUN: %llvm2iceinsts --pnacl %s | %szdiff %s \ ; RUN: %llvm2iceinsts --pnacl %s | %szdiff %s \
...@@ -16,15 +17,19 @@ entry: ...@@ -16,15 +17,19 @@ entry:
ret void ret void
} }
; FuncC is a C symbol that isn't recognized as a C++ mangled symbol. ; FuncC is a C symbol that isn't recognized as a C++ mangled symbol.
; CHECK-LABEL: .text.FuncC
; CHECK: FuncC: ; CHECK: FuncC:
; MANGLE: SubzeroFuncC ; MANGLE-LABEL: .text.SubzeroFuncC
; MANGLE: SubzeroFuncC:
define internal void @_ZN13TestNamespace4FuncEi(i32 %i) { define internal void @_ZN13TestNamespace4FuncEi(i32 %i) {
entry: entry:
ret void ret void
} }
; This is Func(int) nested inside namespace TestNamespace. ; This is Func(int) nested inside namespace TestNamespace.
; CHECK-LABEL: .text._ZN13TestNamespace4FuncEi
; CHECK: _ZN13TestNamespace4FuncEi: ; CHECK: _ZN13TestNamespace4FuncEi:
; MANGLE-LABEL: .text._ZN7Subzero13TestNamespace4FuncEi
; MANGLE: _ZN7Subzero13TestNamespace4FuncEi: ; MANGLE: _ZN7Subzero13TestNamespace4FuncEi:
define internal void @_ZN13TestNamespace15NestedNamespace4FuncEi(i32 %i) { define internal void @_ZN13TestNamespace15NestedNamespace4FuncEi(i32 %i) {
...@@ -32,7 +37,9 @@ entry: ...@@ -32,7 +37,9 @@ entry:
ret void ret void
} }
; This is Func(int) nested inside two namespaces. ; This is Func(int) nested inside two namespaces.
; CHECK-LABEL: .text._ZN13TestNamespace15NestedNamespace4FuncEi
; CHECK: _ZN13TestNamespace15NestedNamespace4FuncEi: ; CHECK: _ZN13TestNamespace15NestedNamespace4FuncEi:
; MANGLE-LABEL: .text._ZN7Subzero13TestNamespace15NestedNamespace4FuncEi
; MANGLE: _ZN7Subzero13TestNamespace15NestedNamespace4FuncEi: ; MANGLE: _ZN7Subzero13TestNamespace15NestedNamespace4FuncEi:
define internal void @_Z13FuncCPlusPlusi(i32 %i) { define internal void @_Z13FuncCPlusPlusi(i32 %i) {
...@@ -40,7 +47,9 @@ entry: ...@@ -40,7 +47,9 @@ entry:
ret void ret void
} }
; This is a non-nested, mangled C++ symbol. ; This is a non-nested, mangled C++ symbol.
; CHECK-LABEL: .text._Z13FuncCPlusPlusi
; CHECK: _Z13FuncCPlusPlusi: ; CHECK: _Z13FuncCPlusPlusi:
; MANGLE-LABEL: .text._ZN7Subzero13FuncCPlusPlusEi
; MANGLE: _ZN7Subzero13FuncCPlusPlusEi: ; MANGLE: _ZN7Subzero13FuncCPlusPlusEi:
define internal void @_ZN12_GLOBAL__N_18FuncAnonEi(i32 %i) { define internal void @_ZN12_GLOBAL__N_18FuncAnonEi(i32 %i) {
...@@ -48,7 +57,9 @@ entry: ...@@ -48,7 +57,9 @@ entry:
ret void ret void
} }
; This is FuncAnon(int) nested inside an anonymous namespace. ; This is FuncAnon(int) nested inside an anonymous namespace.
; CHECK-LABEL: .text._ZN12_GLOBAL__N_18FuncAnonEi
; CHECK: _ZN12_GLOBAL__N_18FuncAnonEi: ; CHECK: _ZN12_GLOBAL__N_18FuncAnonEi:
; MANGLE-LABEL: .text._ZN7Subzero12_GLOBAL__N_18FuncAnonEi
; MANGLE: _ZN7Subzero12_GLOBAL__N_18FuncAnonEi: ; MANGLE: _ZN7Subzero12_GLOBAL__N_18FuncAnonEi:
; Now for the illegitimate examples. ; Now for the illegitimate examples.
...@@ -58,6 +69,7 @@ define internal void @_ZN(i32 %i) { ...@@ -58,6 +69,7 @@ define internal void @_ZN(i32 %i) {
entry: entry:
ret void ret void
} }
; MANGLE-LABEL: .text.Subzero_ZN
; MANGLE: Subzero_ZN: ; MANGLE: Subzero_ZN:
; Test for _Z<len><str> where <len> is smaller than it should be. ; Test for _Z<len><str> where <len> is smaller than it should be.
...@@ -65,6 +77,7 @@ define internal void @_Z12FuncCPlusPlusi(i32 %i) { ...@@ -65,6 +77,7 @@ define internal void @_Z12FuncCPlusPlusi(i32 %i) {
entry: entry:
ret void ret void
} }
; MANGLE-LABEL: .text._ZN7Subzero12FuncCPlusPluEsi
; MANGLE: _ZN7Subzero12FuncCPlusPluEsi: ; MANGLE: _ZN7Subzero12FuncCPlusPluEsi:
; Test for _Z<len><str> where <len> is slightly larger than it should be. ; Test for _Z<len><str> where <len> is slightly larger than it should be.
...@@ -72,6 +85,7 @@ define internal void @_Z14FuncCPlusPlusi(i32 %i) { ...@@ -72,6 +85,7 @@ define internal void @_Z14FuncCPlusPlusi(i32 %i) {
entry: entry:
ret void ret void
} }
; MANGLE-LABEL: .text._ZN7Subzero14FuncCPlusPlusiE
; MANGLE: _ZN7Subzero14FuncCPlusPlusiE: ; MANGLE: _ZN7Subzero14FuncCPlusPlusiE:
; Test for _Z<len><str> where <len> is much larger than it should be. ; Test for _Z<len><str> where <len> is much larger than it should be.
...@@ -79,6 +93,7 @@ define internal void @_Z114FuncCPlusPlusi(i32 %i) { ...@@ -79,6 +93,7 @@ define internal void @_Z114FuncCPlusPlusi(i32 %i) {
entry: entry:
ret void ret void
} }
; MANGLE-LABEL: .text.Subzero_Z114FuncCPlusPlusi
; MANGLE: Subzero_Z114FuncCPlusPlusi: ; MANGLE: Subzero_Z114FuncCPlusPlusi:
; Test for _Z<len><str> where we try to overflow the uint32_t holding <len>. ; Test for _Z<len><str> where we try to overflow the uint32_t holding <len>.
...@@ -86,6 +101,7 @@ define internal void @_Z4294967296FuncCPlusPlusi(i32 %i) { ...@@ -86,6 +101,7 @@ define internal void @_Z4294967296FuncCPlusPlusi(i32 %i) {
entry: entry:
ret void ret void
} }
; MANGLE-LABEL: .text.Subzero_Z4294967296FuncCPlusPlusi
; MANGLE: Subzero_Z4294967296FuncCPlusPlusi: ; MANGLE: Subzero_Z4294967296FuncCPlusPlusi:
; Test for _Z<len><str> where <len> is 0. ; Test for _Z<len><str> where <len> is 0.
...@@ -93,6 +109,7 @@ define internal void @_Z0FuncCPlusPlusi(i32 %i) { ...@@ -93,6 +109,7 @@ define internal void @_Z0FuncCPlusPlusi(i32 %i) {
entry: entry:
ret void ret void
} }
; MANGLE-LABEL: .text._ZN7Subzero0EFuncCPlusPlusi
; MANGLE: _ZN7Subzero0EFuncCPlusPlusi: ; MANGLE: _ZN7Subzero0EFuncCPlusPlusi:
; Test for _Z<len><str> where <len> is -1. LLVM explicitly allows the ; Test for _Z<len><str> where <len> is -1. LLVM explicitly allows the
...@@ -102,6 +119,7 @@ define internal void @_Z-1FuncCPlusPlusi(i32 %i) { ...@@ -102,6 +119,7 @@ define internal void @_Z-1FuncCPlusPlusi(i32 %i) {
entry: entry:
ret void ret void
} }
; MANGLE-LABEL: .text.Subzero_Z-1FuncCPlusPlusi
; MANGLE: Subzero_Z-1FuncCPlusPlusi: ; MANGLE: Subzero_Z-1FuncCPlusPlusi:
...@@ -115,6 +133,7 @@ entry: ...@@ -115,6 +133,7 @@ entry:
; (to test parser edge cases) ; (to test parser edge cases)
define internal void @_Z3fooP10MyClassS1xP10MyClassS2xRS_RS1_S_S1_SZZZ_SZ9ZZ_S12345() { define internal void @_Z3fooP10MyClassS1xP10MyClassS2xRS_RS1_S_S1_SZZZ_SZ9ZZ_S12345() {
; MANGLE-LABEL: .text._ZN7Subzero3fooEP10MyClassS1xP10MyClassS2xRS0_RS2_S0_S2_S1000_SZA00_S12345
; MANGLE: _ZN7Subzero3fooEP10MyClassS1xP10MyClassS2xRS0_RS2_S0_S2_S1000_SZA00_S12345: ; MANGLE: _ZN7Subzero3fooEP10MyClassS1xP10MyClassS2xRS0_RS2_S0_S2_S1000_SZA00_S12345:
entry: entry:
ret void ret void
...@@ -122,6 +141,7 @@ entry: ...@@ -122,6 +141,7 @@ entry:
; Test that unmangled (non-C++) strings don't have substitutions updated. ; Test that unmangled (non-C++) strings don't have substitutions updated.
define internal void @foo_S_S0_SZ_S() { define internal void @foo_S_S0_SZ_S() {
; MANGLE-LABEL: .text.Subzerofoo_S_S0_SZ_S
; MANGLE: Subzerofoo_S_S0_SZ_S: ; MANGLE: Subzerofoo_S_S0_SZ_S:
entry: entry:
ret void ret void
......
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