Goodbye macro hell, hello nice clean and simple code. This also gives llc

the ability to dynamically load and use targets that are not linked into it
statically.  e.g.:

  llc -load libparisc.so -march=parisc foo.bc -o foo.s


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14751 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2004-07-11 04:03:24 +00:00
parent d5e1d9d5f4
commit e45110e012

View File

@ -14,13 +14,14 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Bytecode/Reader.h" #include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/PassManager.h" #include "llvm/PassManager.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "Support/CommandLine.h" #include "Support/CommandLine.h"
#include "Support/PluginLoader.h"
#include "llvm/System/Signals.h" #include "llvm/System/Signals.h"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
@ -40,21 +41,13 @@ OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
static cl::opt<bool> Force("f", cl::desc("Overwrite output files")); static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
enum ArchName { noarch, X86, SparcV9, PowerPC, CBackend };
static cl::opt<ArchName>
Arch("march", cl::desc("Architecture to generate assembly for:"), cl::Prefix,
cl::values(clEnumValN(X86, "x86", " IA-32 (Pentium and above)"),
clEnumValN(SparcV9, "sparcv9", " SPARC V9"),
clEnumValN(PowerPC, "powerpc", " PowerPC (experimental)"),
clEnumValN(CBackend, "c", " C backend"),
0),
cl::init(noarch));
static cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser>
MArch("march", cl::desc("Architecture to generate assembly for:"));
// GetFileNameRoot - Helper function to get the basename of a filename... // GetFileNameRoot - Helper function to get the basename of a filename...
static inline std::string static inline std::string
GetFileNameRoot(const std::string &InputFilename) GetFileNameRoot(const std::string &InputFilename) {
{
std::string IFN = InputFilename; std::string IFN = InputFilename;
std::string outputFilename; std::string outputFilename;
int Len = IFN.length(); int Len = IFN.length();
@ -86,52 +79,18 @@ int main(int argc, char **argv) {
// explicitly specified an architecture to compile for. // explicitly specified an architecture to compile for.
TargetMachine* (*TargetMachineAllocator)(const Module&, TargetMachine* (*TargetMachineAllocator)(const Module&,
IntrinsicLowering *) = 0; IntrinsicLowering *) = 0;
switch (Arch) { if (MArch == 0) {
case CBackend: std::string Err;
TargetMachineAllocator = allocateCTargetMachine; MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
break; if (MArch == 0) {
case X86: std::cerr << argv[0] << ": error auto-selecting target for module '"
TargetMachineAllocator = allocateX86TargetMachine; << Err << "'. Please use the -march option to explicitly "
break; << "pick a target.\n";
case SparcV9:
TargetMachineAllocator = allocateSparcV9TargetMachine;
break;
case PowerPC:
TargetMachineAllocator = allocatePowerPCTargetMachine;
break;
default:
// Decide what the default target machine should be, by looking at
// the module. This heuristic (ILP32, LE -> IA32; LP64, BE ->
// SPARCV9) is kind of gross, but it will work until we have more
// sophisticated target information to work from.
if (mod.getEndianness() == Module::LittleEndian &&
mod.getPointerSize() == Module::Pointer32) {
TargetMachineAllocator = allocateX86TargetMachine;
} else if (mod.getEndianness() == Module::BigEndian &&
mod.getPointerSize() == Module::Pointer32) {
TargetMachineAllocator = allocatePowerPCTargetMachine;
} else if (mod.getEndianness() == Module::BigEndian &&
mod.getPointerSize() == Module::Pointer64) {
TargetMachineAllocator = allocateSparcV9TargetMachine;
} else {
// If the module is target independent, favor a target which matches the
// current build system.
#if defined(i386) || defined(__i386__) || defined(__x86__)
TargetMachineAllocator = allocateX86TargetMachine;
#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9)
TargetMachineAllocator = allocateSparcV9TargetMachine;
#elif defined(__POWERPC__) || defined(__ppc__) || defined(__APPLE__)
TargetMachineAllocator = allocatePowerPCTargetMachine;
#else
std::cerr << argv[0] << ": module does not specify a target to use. "
<< "You must use the -march option. If no native target is "
<< "available, use -march=c to emit C code.\n";
return 1; return 1;
#endif }
}
break;
} }
std::auto_ptr<TargetMachine> target(TargetMachineAllocator(mod, 0));
std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0));
assert(target.get() && "Could not allocate target machine!"); assert(target.get() && "Could not allocate target machine!");
TargetMachine &Target = *target.get(); TargetMachine &Target = *target.get();
const TargetData &TD = Target.getTargetData(); const TargetData &TD = Target.getTargetData();
@ -169,7 +128,7 @@ int main(int argc, char **argv) {
} else { } else {
OutputFilename = GetFileNameRoot(InputFilename); OutputFilename = GetFileNameRoot(InputFilename);
if (Arch != CBackend) if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
OutputFilename += ".s"; OutputFilename += ".s";
else else
OutputFilename += ".cbe.c"; OutputFilename += ".cbe.c";