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_ {
#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) {
size_t TotalTests = 0;
size_t Passes = 0;
......
......@@ -14,9 +14,11 @@
#ifndef SUBZERO_SRC_ICECONVERTER_H
#define SUBZERO_SRC_ICECONVERTER_H
#include "IceDefs.h"
#include "IceTranslator.h"
namespace llvm {
class GlobalValue;
class Module;
}
......@@ -27,18 +29,42 @@ public:
Converter(llvm::Module *Mod, GlobalContext *Ctx, const Ice::ClFlags &Flags)
: Translator(Ctx, Flags), Mod(Mod) {}
~Converter() {}
/// Converts the LLVM Module to ICE. Sets exit status to false if successful,
/// true otherwise.
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:
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.
void convertFunctions();
// Converts globals to ICE, and then machine code.
void convertGlobals(llvm::Module *Mod);
// Installs global declarations into GlobalDeclarationMap.
void installGlobalDeclarations(llvm::Module *Mod);
Converter(const Converter &) = delete;
Converter &operator=(const Converter &) = delete;
};
......
......@@ -26,7 +26,6 @@
#include <set>
#include <string>
#include <vector>
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallBitVector.h"
......@@ -39,7 +38,9 @@ namespace Ice {
class Cfg;
class CfgNode;
class Constant;
class FunctionDeclaration;
class GlobalContext;
class GlobalDeclaration;
class Inst;
class InstPhi;
class InstTarget;
......@@ -48,6 +49,7 @@ class Liveness;
class Operand;
class TargetLowering;
class Variable;
class VariableDeclaration;
class VariablesMetadata;
// TODO: Switch over to LLVM's ADT container classes.
......
......@@ -19,6 +19,7 @@
#include "IceClFlags.h"
#include "IceDefs.h"
#include "IceGlobalContext.h"
#include "IceGlobalInits.h"
#include "IceOperand.h"
#include "IceTargetLowering.h"
#include "IceTimerTree.h"
......@@ -289,7 +290,9 @@ IceString GlobalContext::mangleName(const IceString &Name) const {
return getTestPrefix() + Name;
}
GlobalContext::~GlobalContext() {}
GlobalContext::~GlobalContext() {
llvm::DeleteContainerPointers(GlobalDeclarations);
}
Constant *GlobalContext::getConstantInt64(Type Ty, uint64_t ConstantInt64) {
assert(Ty == IceType_i64);
......@@ -385,6 +388,23 @@ ConstantList GlobalContext::getConstantPool(Type Ty) const {
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,
const IceString &Name) {
assert(StackID < Timers.size());
......
......@@ -21,6 +21,7 @@
#include "llvm/Support/raw_ostream.h"
#include "IceDefs.h"
#include "IceClFlags.h"
#include "IceIntrinsics.h"
#include "IceRNG.h"
#include "IceTimerTree.h"
......@@ -29,6 +30,7 @@
namespace Ice {
class ClFlags;
class FuncSigType;
// This class collects rudimentary statistics during translation.
class CodeStats {
......@@ -117,6 +119,17 @@ public:
// getConstantPool() returns a copy of the constant pool for
// constants of a given type.
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; }
......@@ -186,6 +199,7 @@ private:
CodeStats StatsFunction;
CodeStats StatsCumulative;
std::vector<TimerStack> Timers;
std::vector<GlobalDeclaration *> GlobalDeclarations;
GlobalContext(const GlobalContext &) = delete;
GlobalContext &operator=(const GlobalContext &) = delete;
......
//===- subzero/src/IceGlobalInits.cpp - Global initializers ---------------===//
//===- subzero/src/IceGlobalInits.cpp - Global declarations ---------------===//
//
// The Subzero Code Generator
//
......@@ -7,8 +7,9 @@
//
//===----------------------------------------------------------------------===//
//
// This file implements the notion of global addresses and
// initializers in Subzero.
// This file implements the notion of function declarations, global
// variable declarations, and the corresponding variable initializers
// in Subzero.
//
//===----------------------------------------------------------------------===//
......@@ -17,18 +18,82 @@
#include "llvm/IR/Value.h"
#include "IceDefs.h"
#include "IceGlobalContext.h"
#include "IceGlobalInits.h"
#include "IceTypes.h"
namespace {
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 {
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 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();
}
void GlobalAddress::dumpType(Ostream &Stream) const {
VariableDeclaration::~VariableDeclaration() {
llvm::DeleteContainerPointers(Initializers);
}
void VariableDeclaration::dumpType(Ostream &Stream) const {
if (Initializers.size() == 1) {
Initializers.front()->dumpType(Stream);
} else {
......@@ -46,8 +111,8 @@ void GlobalAddress::dumpType(Ostream &Stream) const {
}
}
void GlobalAddress::dump(Ostream &Stream) const {
Stream << "@" << getName() << " = internal "
void VariableDeclaration::dump(Ostream &Stream) const {
Stream << "@" << Name << " = internal "
<< (IsConstant ? "constant" : "global") << " ";
// Add initializer.
......@@ -74,11 +139,11 @@ void GlobalAddress::dump(Ostream &Stream) const {
Stream << "\n";
}
void GlobalAddress::Initializer::dumpType(Ostream &Stream) const {
void VariableDeclaration::Initializer::dumpType(Ostream &Stream) const {
Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]";
}
void GlobalAddress::DataInitializer::dump(Ostream &Stream) const {
void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const {
dumpType(Stream);
Stream << " c\"";
// Code taken from PrintEscapedString() in AsmWriter.cpp. Keep
......@@ -93,41 +158,24 @@ void GlobalAddress::DataInitializer::dump(Ostream &Stream) const {
Stream << "\"";
}
void GlobalAddress::ZeroInitializer::dump(Ostream &Stream) const {
void VariableDeclaration::ZeroInitializer::dump(Ostream &Stream) const {
dumpType(Stream);
Stream << " zeroinitializer";
}
IceString GlobalAddress::RelocInitializer::getName() 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 {
void VariableDeclaration::RelocInitializer::dumpType(Ostream &Stream) const {
Stream << Ice::IceType_i32;
}
void GlobalAddress::RelocInitializer::dump(Ostream &Stream) const {
void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const {
if (Offset != 0) {
dumpType(Stream);
Stream << " add (";
}
dumpType(Stream);
Stream << " ptrtoint (";
if (Address.getKind() == FunctionRelocation) {
Stream << *Address.getFunction()->getType() << " @"
<< Address.getFunction()->getName();
} else {
Address.getGlobalAddr()->dumpType(Stream);
Stream << "* @" << Address.getGlobalAddr()->getName();
}
Stream << " to ";
Declaration->dumpType(Stream);
Stream << "* @" << Declaration->getName() << " to ";
dumpType(Stream);
Stream << ")";
if (Offset != 0) {
......@@ -136,4 +184,5 @@ void GlobalAddress::RelocInitializer::dump(Ostream &Stream) const {
Stream << " " << Offset << ")";
}
}
}
} // end of namespace Ice
......@@ -27,7 +27,6 @@ namespace Ice {
typedef uint8_t AsmCodeByte;
class Assembler;
class GlobalAddress;
// LoweringContext makes it easy to iterate through non-deleted
// instructions in a node, and insert new (lowered) instructions at
......@@ -249,7 +248,7 @@ public:
GlobalContext *Ctx);
virtual ~TargetGlobalInitLowering();
virtual void lower(const GlobalAddress &Addr, bool DisableTranslation) = 0;
virtual void lower(const VariableDeclaration &Var) = 0;
protected:
TargetGlobalInitLowering(GlobalContext *Ctx) : Ctx(Ctx) {}
......
......@@ -4427,32 +4427,19 @@ void ConstantUndef::emit(GlobalContext *) const {
TargetGlobalInitX8632::TargetGlobalInitX8632(GlobalContext *Ctx)
: TargetGlobalInitLowering(Ctx) {}
void TargetGlobalInitX8632::lower(const GlobalAddress &Global,
bool DisableTranslation) {
if (Ctx->isVerbose()) {
Global.dump(Ctx->getStrDump());
}
if (DisableTranslation)
return;
void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
Ostream &Str = Ctx->getStrEmit();
// TODO(kschimpf): Don't mangle name if external and uninitialized. This
// will allow us to cross test relocations for references to external
// global variables.
const GlobalAddress::InitializerListType &Initializers =
Global.getInitializers();
const VariableDeclaration::InitializerListType &Initializers =
Var.getInitializers();
assert(Initializers.size());
bool HasInitializer =
!(Initializers.size() == 1 &&
llvm::isa<GlobalAddress::ZeroInitializer>(Initializers[0]));
bool IsConstant = Global.getIsConstant();
bool IsExternal = !Global.getIsInternal();
uint32_t Align = Global.getAlignment();
SizeT Size = Global.getNumBytes();
IceString MangledName = Ctx->mangleName(Global.getName());
bool HasInitializer = Var.hasInitializer();
bool IsConstant = Var.getIsConstant();
bool IsExternal = Var.getIsExternal();
uint32_t Align = Var.getAlignment();
SizeT Size = Var.getNumBytes();
IceString MangledName = Var.mangleName(Ctx);
IceString SectionSuffix = "";
if (Ctx->getFlags().DataSections)
SectionSuffix = "." + MangledName;
......@@ -4483,30 +4470,29 @@ void TargetGlobalInitX8632::lower(const GlobalAddress &Global,
Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n";
if (HasInitializer) {
for (GlobalAddress::Initializer *Init : Initializers) {
for (VariableDeclaration::Initializer *Init : Initializers) {
switch (Init->getKind()) {
case GlobalAddress::Initializer::DataInitializerKind: {
const auto Data =
llvm::cast<GlobalAddress::DataInitializer>(Init)->getContents();
case VariableDeclaration::Initializer::DataInitializerKind: {
const auto Data = llvm::cast<VariableDeclaration::DataInitializer>(Init)
->getContents();
for (SizeT i = 0; i < Init->getNumBytes(); ++i) {
Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
}
break;
}
case GlobalAddress::Initializer::ZeroInitializerKind:
case VariableDeclaration::Initializer::ZeroInitializerKind:
Str << "\t.zero\t" << Init->getNumBytes() << "\n";
break;
case GlobalAddress::Initializer::RelocInitializerKind: {
const auto Reloc = llvm::cast<GlobalAddress::RelocInitializer>(Init);
case VariableDeclaration::Initializer::RelocInitializerKind: {
const auto Reloc =
llvm::cast<VariableDeclaration::RelocInitializer>(Init);
Str << "\t.long\t";
// TODO(kschimpf): Once the representation of a relocation has
// been modified to reference the corresponding global
// address, modify to not mangle the name if the global is
// 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 << Reloc->getDeclaration()->mangleName(Ctx);
if (VariableDeclaration::RelocOffsetType Offset = Reloc->getOffset()) {
if (Offset >= 0 || (Offset == INT32_MIN))
Str << " + " << Offset;
else
Str << " - " << -Offset;
}
Str << "\n";
break;
......
......@@ -482,8 +482,7 @@ public:
return new TargetGlobalInitX8632(Ctx);
}
virtual void lower(const GlobalAddress &Addr,
bool DisableTranslation) override;
virtual void lower(const VariableDeclaration &Var) final;
protected:
TargetGlobalInitX8632(GlobalContext *Ctx);
......
......@@ -22,6 +22,7 @@
#include "IceCfg.h"
#include "IceClFlags.h"
#include "IceDefs.h"
#include "IceGlobalInits.h"
#include "IceTargetLowering.h"
#include "IceTranslator.h"
......@@ -54,38 +55,6 @@ bool Translator::checkIfUnnamedNameSafe(const IceString &Name, const char *Kind,
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) {
Ctx->resetStats();
Func.reset(Fcn);
......@@ -110,12 +79,18 @@ void Translator::emitConstants() {
Func->getTarget()->emitConstants();
}
void Translator::lowerGlobals(const GlobalAddressList &GlobalAddresses) {
llvm::OwningPtr<Ice::TargetGlobalInitLowering> GlobalLowering(
Ice::TargetGlobalInitLowering::createLowering(Ctx->getTargetArch(), Ctx));
void Translator::lowerGlobals(
const VariableDeclarationListType &VariableDeclarations) {
llvm::OwningPtr<TargetGlobalInitLowering> GlobalLowering(
TargetGlobalInitLowering::createLowering(Ctx->getTargetArch(), Ctx));
bool DisableTranslation = Ctx->getFlags().DisableTranslation;
for (const Ice::GlobalAddress *Addr : GlobalAddresses) {
GlobalLowering->lower(*Addr, DisableTranslation);
bool DumpGlobalVariables = Ctx->isVerbose();
Ostream &Stream = Ctx->getStrDump();
for (const Ice::VariableDeclaration *Global : VariableDeclarations) {
if (DumpGlobalVariables)
Global->dump(Stream);
if(!DisableTranslation)
GlobalLowering->lower(*Global);
}
GlobalLowering.reset();
}
......@@ -25,16 +25,15 @@ namespace Ice {
class ClFlags;
class Cfg;
class GlobalAddress;
class VariableDeclaration;
class GlobalContext;
// Base class for translating ICE to machine code.
// Derived classes convert other intermediate representations down to ICE,
// and then call the appropriate (inherited) methods to convert ICE into
// machine instructions.
// Base class for translating ICE to machine code. Derived classes convert
// other intermediate representations down to ICE, and then call the appropriate
// (inherited) methods to convert ICE into machine instructions.
class Translator {
public:
typedef std::vector<Ice::GlobalAddress *> GlobalAddressList;
typedef std::vector<VariableDeclaration *> VariableDeclarationListType;
Translator(GlobalContext *Ctx, const ClFlags &Flags)
: Ctx(Ctx), Flags(Flags), ErrorStatus(0) {}
......@@ -54,8 +53,9 @@ public:
/// Emits the constant pool.
void emitConstants();
/// Lowers the given list of global addresses to target.
void lowerGlobals(const GlobalAddressList &GlobalAddresses);
/// Lowers the given list of global addresses to target. Generates
/// list of corresponding variable declarations.
void lowerGlobals(const VariableDeclarationListType &VariableDeclarations);
/// Creates a name using the given prefix and corresponding index.
std::string createUnnamedName(const IceString &Prefix, SizeT Index);
......@@ -66,15 +66,6 @@ public:
bool checkIfUnnamedNameSafe(const IceString &Name, const char *Kind,
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:
GlobalContext *Ctx;
const ClFlags &Flags;
......
; Test of global initializers.
; Check that we generate proper global initializers.
; RUN: %p2i -i %s --args -verbose inst | 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
; RUN: %l2i -i %s --insts | FileCheck %s
; RUN: %p2i -i %s --insts | FileCheck %s
@PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
; CHECK: .type PrimitiveInit,@object
; CHECK-NEXT: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: PrimitiveInit:
; CHECK-NEXT: .byte
; CHECK: .size PrimitiveInit, 4
; CHECK: @PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
@PrimitiveInitConst = internal constant [4 x i8] c"\0D\00\00\00", align 4
; CHECK: .type PrimitiveInitConst,@object
; CHECK-NEXT: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: PrimitiveInitConst:
; CHECK-NEXT: .byte
; CHECK: .size PrimitiveInitConst, 4
; CHECK-NEXT: @PrimitiveInitConst = internal constant [4 x i8] c"\0D\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: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayInit:
; CHECK-NEXT: .byte
; CHECK: .size ArrayInit, 20
; 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
@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: .section .data,"aw",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayInitPartial:
; CHECK-NEXT: .byte
; CHECK: .size ArrayInitPartial, 40
; 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
@PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .type PrimitiveInitStatic,@object
; CHECK-NEXT: .local PrimitiveInitStatic
; CHECK-NEXT: .comm PrimitiveInitStatic,4,4
; CHECK-NEXT: @PrimitiveInitStatic = internal global [4 x i8] zeroinitializer, align 4
@PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4
; CHECK: .type PrimitiveUninit,@object
; CHECK-NEXT: .local PrimitiveUninit
; CHECK-NEXT: .comm PrimitiveUninit,4,4
; CHECK-NEXT: @PrimitiveUninit = internal global [4 x i8] zeroinitializer, align 4
@ArrayUninit = internal global [20 x i8] zeroinitializer, align 4
; CHECK: .type ArrayUninit,@object
; CHECK-NEXT: .local ArrayUninit
; CHECK-NEXT: .comm ArrayUninit,20,4
; CHECK-NEXT: @ArrayUninit = internal global [20 x i8] zeroinitializer, align 4
@ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8
; CHECK: .type ArrayUninitConstDouble,@object
; CHECK-NEXT: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 8
; CHECK-NEXT: ArrayUninitConstDouble:
; CHECK-NEXT: .zero 200
; CHECK-NEXT: .size ArrayUninitConstDouble, 200
; CHECK-NEXT: @ArrayUninitConstDouble = internal constant [200 x i8] zeroinitializer, align 8
@ArrayUninitConstInt = internal constant [20 x i8] zeroinitializer, align 4
; CHECK: .type ArrayUninitConstInt,@object
; CHECK: .section .rodata,"a",@progbits
; CHECK-NEXT: .align 4
; CHECK-NEXT: ArrayUninitConstInt:
; CHECK-NEXT: .zero 20
; CHECK-NEXT: .size ArrayUninitConstInt, 20
; CHECK-NEXT: @ArrayUninitConstInt = internal constant [20 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
; CHECK: @__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4
@__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
; CHECK: @__tls_template_alignment = internal constant [4 x i8] c"\01\00\00\00", align 4
define internal i32 @main(i32 %argc, i32 %argv) {
entry:
......@@ -96,28 +61,6 @@ entry:
call void @use(i32 %expanded13)
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)
......
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