Commit d442e7ee by Jim Stichnoth

Subzero: Use -filetype instead of -ias and -elf-writer.

This matches LLVM's -filetype={obj,asm} options, and also adds -filetype=iasm to get textual rendering with the integrated assembler. It also removes the old illegal combination of -ias=0 -elf-writer. BUG= none R=jvoung@chromium.org, kschimpf@google.com Review URL: https://codereview.chromium.org/920953002
parent bbca754a
......@@ -61,7 +61,9 @@ following:
``-target=<TARGET>`` -- Set the target architecture. The default is x8632.
Future targets include x8664, arm32, and arm64.
``-integrated-as=0|1`` -- Disable/enable the integrated assembler.
``-filetype=obj|asm|iasm`` -- Select the output file type. ``obj`` is a
native ELF file, ``asm`` is a textual assembly file, and ``iasm`` is a
low-level textual assembly file demonstrating the integrated assembler.
``-O<LEVEL>`` -- Set the optimization level. Valid levels are ``2``, ``1``,
``0``, ``-1``, and ``m1``. Levels ``-1`` and ``m1`` are synonyms, and
......@@ -103,15 +105,16 @@ A convenient way to run both the lit tests and the cross tests is::
make -f Makefile.standalone check
Assembling ``llvm2ice`` output
------------------------------
Assembling ``llvm2ice`` output as needed
----------------------------------------
Currently ``llvm2ice`` produces textual assembly code in a structure suitable
for input to ``llvm-mc``. An object file can be produced using the command::
``llvm2ice`` can now produce a native ELF binary using ``-filetype=obj``.
llvm-mc -arch=x86 -filetype=obj -o=MyObj.o
``llvm2ice`` can also produce textual assembly code in a structure suitable for
input to ``llvm-mc``, using ``-filetype=asm`` or ``-filetype=iasm``. An object
file can then be produced using the command::
In the future, the integrated assembler will directly produce ELF object files.
llvm-mc -arch=x86 -filetype=obj -o=MyObj.o
Building a translated binary
----------------------------
......
......@@ -80,9 +80,9 @@ def AddOptionalArgs(argparser):
help='Optimization level ' +
'(m1 and -1 are equivalent).' +
' Default %(default)s.')
argparser.add_argument('--elf', dest='elf',
action='store_true',
help='Directly generate ELF output')
argparser.add_argument('--filetype', default='iasm', dest='filetype',
choices=['obj', 'asm', 'iasm'],
help='Output file type. Default %(default)s.')
argparser.add_argument('--verbose', '-v', dest='verbose',
action='store_true',
help='Display some extra debugging output')
......@@ -205,15 +205,15 @@ def ProcessPexe(args, pexe, exe):
shellcmd([llvm2ice,
'-O' + opt_level,
'-bitcode-format=pnacl',
'-o', obj_sz if args.elf else asm_sz] +
'-filetype=' + args.filetype,
'-o', obj_sz if args.filetype == 'obj' else asm_sz] +
(['-externalize',
'-ffunction-sections',
'-fdata-sections'] if hybrid else []) +
(['-elf-writer'] if args.elf else []) +
args.sz_args +
[pexe],
echo=args.verbose)
if not args.elf:
if args.filetype != 'obj':
shellcmd((
'llvm-mc -arch=x86 -filetype=obj -o {obj} {asm}'
).format(asm=asm_sz, obj=obj_sz), echo=args.verbose)
......
......@@ -31,8 +31,9 @@ public:
DisableTranslation(false), DumpStats(false), FunctionSections(false),
GenerateUnitTestMessages(false), PhiEdgeSplit(false),
StubConstantCalls(false), SubzeroTimingEnabled(false),
TimeEachFunction(false), UseELFWriter(false),
UseIntegratedAssembler(false), UseSandboxing(false),
TimeEachFunction(false), UseSandboxing(false),
// FileType field
OutFileType(FT_Iasm),
// IceString fields.
DefaultFunctionPrefix(""), DefaultGlobalPrefix(""), TimingFocusOn(""),
TranslateOnly(""), VerboseFocusOn(""),
......@@ -99,17 +100,13 @@ public:
bool getTimeEachFunction() const { return ALLOW_DUMP && TimeEachFunction; }
void setTimeEachFunction(bool NewValue) { TimeEachFunction = NewValue; }
bool getUseELFWriter() const { return UseELFWriter; }
void setUseELFWriter(bool NewValue) { UseELFWriter = NewValue; }
bool getUseIntegratedAssembler() const { return UseIntegratedAssembler; }
void setUseIntegratedAssembler(bool NewValue) {
UseIntegratedAssembler = NewValue;
}
bool getUseSandboxing() const { return UseSandboxing; }
void setUseSandboxing(bool NewValue) { UseSandboxing = NewValue; }
// FileType accessor.
FileType getOutFileType() const { return OutFileType; }
void setOutFileType(FileType NewValue) { OutFileType = NewValue; }
// IceString accessors.
const IceString &getDefaultFunctionPrefix() const {
......@@ -160,10 +157,10 @@ private:
bool StubConstantCalls;
bool SubzeroTimingEnabled;
bool TimeEachFunction;
bool UseELFWriter;
bool UseIntegratedAssembler;
bool UseSandboxing;
FileType OutFileType;
IceString DefaultFunctionPrefix;
IceString DefaultGlobalPrefix;
IceString TimingFocusOn;
......
......@@ -177,6 +177,12 @@ enum VerboseItem {
};
typedef uint32_t VerboseMask;
enum FileType {
FT_Elf, // ELF .o file
FT_Asm, // Assembly .s file
FT_Iasm // "Integrated assembler" .byte-style .s file
};
typedef llvm::raw_ostream Ostream;
typedef llvm::raw_fd_ostream Fdstream;
......
......@@ -158,8 +158,13 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit,
newTimerStackID("Per-function summary");
}
Timers.initInto(MyTLS->Timers);
if (Flags.getUseELFWriter()) {
switch (Flags.getOutFileType()) {
case FT_Elf:
ObjectWriter.reset(new ELFObjectWriter(*this, *ELFStr));
break;
case FT_Asm:
case FT_Iasm:
break;
}
}
......@@ -193,7 +198,9 @@ void GlobalContext::translateFunctions() {
getStrDump() << "ICE translation error: " << Func->getError() << "\n";
Item = new EmitterWorkItem(Func->getSequenceNumber());
} else {
if (getFlags().getUseIntegratedAssembler()) {
switch (getFlags().getOutFileType()) {
case FT_Elf:
case FT_Iasm: {
Func->emitIAS();
// The Cfg has already emitted into the assembly buffer, so
// stats have been fully collected into this thread's TLS.
......@@ -204,10 +211,12 @@ void GlobalContext::translateFunctions() {
Asm->setFunctionName(Func->getFunctionName());
Asm->setInternal(Func->getInternal());
Item = new EmitterWorkItem(Func->getSequenceNumber(), Asm);
} else {
} break;
case FT_Asm:
// The Cfg has not been emitted yet, so stats are not ready
// to be dumped.
Item = new EmitterWorkItem(Func->getSequenceNumber(), Func.release());
break;
}
}
Cfg::setCurrentCfg(nullptr);
......@@ -283,19 +292,25 @@ void GlobalContext::emitItems() {
std::unique_ptr<Assembler> Asm = Item->getAsm();
Asm->alignFunction();
IceString MangledName = mangleName(Asm->getFunctionName());
if (getFlags().getUseELFWriter()) {
switch (getFlags().getOutFileType()) {
case FT_Elf:
getObjectWriter()->writeFunctionCode(MangledName, Asm->getInternal(),
Asm.get());
} else {
break;
case FT_Iasm: {
OstreamLocker L(this);
Cfg::emitTextHeader(MangledName, this, Asm.get());
Asm->emitIASBytes(this);
} break;
case FT_Asm:
llvm::report_fatal_error("Unexpected FT_Asm");
break;
}
} break;
case EmitterWorkItem::WI_Cfg: {
if (!ALLOW_DUMP)
llvm::report_fatal_error("WI_Cfg work item created inappropriately");
assert(!getFlags().getUseIntegratedAssembler());
assert(getFlags().getOutFileType() == FT_Asm);
std::unique_ptr<Cfg> Func = Item->getCfg();
// Unfortunately, we have to temporarily install the Cfg in TLS
// because Variable::asType() uses the allocator to create the
......
......@@ -4641,10 +4641,13 @@ void TargetDataX8632::lowerGlobal(const VariableDeclaration &Var) const {
void TargetDataX8632::lowerGlobals(
std::unique_ptr<VariableDeclarationList> Vars) const {
if (Ctx->getFlags().getUseELFWriter()) {
switch (Ctx->getFlags().getOutFileType()) {
case FT_Elf: {
ELFObjectWriter *Writer = Ctx->getObjectWriter();
Writer->writeDataSection(*Vars, llvm::ELF::R_386_32);
} else {
} break;
case FT_Asm:
case FT_Iasm: {
const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly();
OstreamLocker L(Ctx);
for (const VariableDeclaration *Var : *Vars) {
......@@ -4652,6 +4655,7 @@ void TargetDataX8632::lowerGlobals(
lowerGlobal(*Var);
}
}
} break;
}
}
......@@ -4716,14 +4720,18 @@ void TargetDataX8632::lowerConstants() const {
return;
// No need to emit constants from the int pool since (for x86) they
// are embedded as immediates in the instructions, just emit float/double.
if (Ctx->getFlags().getUseELFWriter()) {
switch (Ctx->getFlags().getOutFileType()) {
case FT_Elf: {
ELFObjectWriter *Writer = Ctx->getObjectWriter();
Writer->writeConstantPool<ConstantFloat>(IceType_f32);
Writer->writeConstantPool<ConstantDouble>(IceType_f64);
} else {
} break;
case FT_Asm:
case FT_Iasm: {
OstreamLocker L(Ctx);
emitConstantPool<PoolTypeConverter<float>>(Ctx);
emitConstantPool<PoolTypeConverter<double>>(Ctx);
} break;
}
}
......
......@@ -184,18 +184,13 @@ static cl::opt<bool> LLVMVerboseErrors(
"building LLVM IR first"),
cl::init(false));
static cl::opt<bool>
UseIntegratedAssembler("integrated-as",
cl::desc("Use integrated assembler (default yes)"),
cl::init(true));
static cl::alias UseIas("ias", cl::desc("Alias for -integrated-as"),
cl::NotHidden, cl::aliasopt(UseIntegratedAssembler));
static cl::opt<bool>
UseELFWriter("elf-writer",
cl::desc("Use ELF writer with the integrated assembler"),
cl::init(false));
static cl::opt<Ice::FileType> OutFileType(
"filetype", cl::desc("Output file type"), cl::init(Ice::FT_Iasm),
cl::values(clEnumValN(Ice::FT_Elf, "obj", "Native ELF object ('.o') file"),
clEnumValN(Ice::FT_Asm, "asm", "Assembly ('.s') file"),
clEnumValN(Ice::FT_Iasm, "iasm",
"Low-level integrated assembly ('.s') file"),
clEnumValEnd));
static cl::opt<bool> AlwaysExitSuccess(
"exit-success", cl::desc("Exit with success status, even if errors found"),
......@@ -317,10 +312,9 @@ int main(int argc, char **argv) {
Flags.setTimeEachFunction(TimeEachFunction);
Flags.setTimingFocusOn(TimingFocusOn);
Flags.setTranslateOnly(TranslateOnly);
Flags.setUseELFWriter(UseELFWriter);
Flags.setUseIntegratedAssembler(UseIntegratedAssembler);
Flags.setUseSandboxing(UseSandboxing);
Flags.setVerboseFocusOn(VerboseFocusOn);
Flags.setOutFileType(OutFileType);
// Force -build-on-read=0 for .ll files.
const std::string LLSuffix = ".ll";
......@@ -334,7 +328,8 @@ int main(int argc, char **argv) {
std::unique_ptr<Ice::Ostream> Os;
std::unique_ptr<Ice::ELFStreamer> ELFStr;
std::ofstream Ofs;
if (UseELFWriter) {
switch (OutFileType) {
case Ice::FT_Elf: {
if (OutputFilename == "-") {
*Ls << "Error: writing binary ELF to stdout is unsupported\n";
return GetReturnValue(Ice::EC_Args);
......@@ -349,7 +344,9 @@ int main(int argc, char **argv) {
return GetReturnValue(Ice::EC_Args);
}
ELFStr.reset(new Ice::ELFStreamer(*FdOs));
} else {
} break;
case Ice::FT_Asm:
case Ice::FT_Iasm: {
if (OutputFilename != "-") {
Ofs.open(OutputFilename.c_str(), std::ofstream::out);
Os.reset(new raw_os_ostream(Ofs));
......@@ -357,6 +354,7 @@ int main(int argc, char **argv) {
Os.reset(new raw_os_ostream(std::cout));
}
Os->SetUnbuffered();
} break;
}
Ice::GlobalContext Ctx(Ls.get(), Os.get(), ELFStr.get(), VMask, TargetArch,
......@@ -364,7 +362,7 @@ int main(int argc, char **argv) {
Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx);
if (UseELFWriter) {
if (OutFileType == Ice::FT_Elf) {
Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx);
Ctx.getObjectWriter()->writeInitialELFHeader();
}
......@@ -403,7 +401,7 @@ int main(int argc, char **argv) {
Translator->transferErrorCode();
Translator->emitConstants();
if (UseELFWriter) {
if (OutFileType == Ice::FT_Elf) {
Ice::TimerMarker T1(Ice::TimerStack::TT_emit, &Ctx);
Ctx.getObjectWriter()->setUndefinedSyms(Ctx.getConstantExternSyms());
Ctx.getObjectWriter()->writeNonUserSections();
......
......@@ -3,7 +3,7 @@
; REQUIRES: allow_dump
; RUN: %p2i -i %s --args --verbose inst -threads=0 -ias=0 | FileCheck %s
; RUN: %p2i -i %s --args --verbose inst -threads=0 -filetype=asm | FileCheck %s
define i32 @Add(i32 %a, i32 %b) {
; CHECK: define i32 @Add
......
......@@ -3,7 +3,7 @@
; For the integrated ELF writer, we can't pipe the output because we need
; to seek backward and patch up the file headers. So, use a temporary file.
; RUN: %p2i -i %s --args -O2 --verbose none -elf-writer -o %t \
; RUN: %p2i -i %s --args -O2 --verbose none -filetype=obj -o %t \
; RUN: && llvm-readobj -file-headers -sections -section-data \
; RUN: -relocations -symbols %t | FileCheck %s
......@@ -13,7 +13,7 @@
; RUN: -relocations -symbols - | FileCheck %s
; Add a run that shows relocations in code inline.
; RUN: %p2i -i %s --args -O2 --verbose none -elf-writer -o %t \
; RUN: %p2i -i %s --args -O2 --verbose none -filetype=obj -o %t \
; RUN: && llvm-objdump -d -r -x86-asm-syntax=intel %t \
; RUN: | FileCheck --check-prefix=TEXT-RELOCS %s
......
......@@ -3,7 +3,7 @@
; For the integrated ELF writer, we can't pipe the output because we need
; to seek backward and patch up the file headers. So, use a temporary file.
; RUN: %p2i -i %s --args -O2 --verbose none -elf-writer -o %t \
; RUN: %p2i -i %s --args -O2 --verbose none -filetype=obj -o %t \
; RUN: && llvm-readobj -file-headers -sections -section-data \
; RUN: -relocations -symbols %t | FileCheck %s
......
......@@ -2,10 +2,12 @@
; REQUIRES: allow_dump
; Test -ias=0 to test the lea "hack" until we are fully confident in -ias=1
; RUN: %p2i -i %s --args --verbose none -ias=0 | FileCheck %s
; Test -filetype=asm to test the lea "hack" until we are fully confident
; in -filetype=iasm .
; RUN: %p2i -i %s --args --verbose none -filetype=asm | FileCheck %s
; Test -ias=1 and try to cross reference instructions w/ the symbol table.
; Test -filetype=iasm and try to cross reference instructions w/ the
; symbol table.
; RUN: %p2i -i %s --args --verbose none \
; RUN: | llvm-mc -triple=i686-none-nacl -filetype=obj \
; RUN: | llvm-objdump -d -r --symbolize -x86-asm-syntax=intel - \
......
......@@ -2,16 +2,16 @@
; REQUIRES: allow_dump
; Don't use integrated-as because this currently depends on the # variant
; Don't use filetype=iasm because this currently depends on the # variant
; assembler comment.
; RUN: %p2i -i %s -a -sz-seed=1 -nop-insertion -nop-insertion-percentage=50 \
; RUN: -max-nops-per-instruction=1 -integrated-as=false \
; RUN: -max-nops-per-instruction=1 -filetype=asm \
; RUN: | FileCheck %s --check-prefix=PROB50
; RUN: %p2i -i %s -a -sz-seed=1 -nop-insertion -nop-insertion-percentage=90 \
; RUN: -max-nops-per-instruction=1 -integrated-as=false \
; RUN: -max-nops-per-instruction=1 -filetype=asm \
; RUN: | FileCheck %s --check-prefix=PROB90
; RUN: %p2i -i %s -a -sz-seed=1 -nop-insertion -nop-insertion-percentage=50 \
; RUN: -max-nops-per-instruction=2 -integrated-as=false \
; RUN: -max-nops-per-instruction=2 -filetype=asm \
; RUN: | FileCheck %s --check-prefix=MAXNOPS2
define <4 x i32> @mul_v4i32(<4 x i32> %a, <4 x i32> %b) {
......
......@@ -28,7 +28,7 @@ bool IceTest::SubzeroBitcodeMunger::runTest(const char *TestName,
Ice::ClFlags Flags;
Flags.setAllowErrorRecovery(true);
Flags.setGenerateUnitTestMessages(true);
Flags.setUseIntegratedAssembler(true); // for the MINIMAL build
Flags.setOutFileType(Ice::FT_Iasm);
Ice::GlobalContext Ctx(DumpStream, DumpStream, nullptr,
Ice::IceV_Instructions, Ice::Target_X8632, Ice::Opt_m1,
"", Flags);
......
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