diff options
author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-09-16 15:39:26 +0000 |
---|---|---|
committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-09-16 15:39:26 +0000 |
commit | e1f7280bf8b54ea263ea146a94e287da8acb3c46 (patch) | |
tree | 58f96c3cd30bf507b780f4923759df4352301a5a /lib/Target/TargetMachine.cpp | |
parent | 00020d3d01ef91080ca6ba9790b2b198e8543895 (diff) |
Move all the code that creates code generation passes from Sparc.cpp to
TargetMachine.cpp, since it is entirely machine-independent.
Also, add options to disable optional back-end passes (preselection and
instr. scheduling).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3740 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/TargetMachine.cpp')
-rw-r--r-- | lib/Target/TargetMachine.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index 69c7cfd428..84149f8934 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -8,9 +8,31 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/MachineInstrInfo.h" #include "llvm/Target/MachineCacheInfo.h" +#include "llvm/CodeGen/PreSelection.h" +#include "llvm/CodeGen/InstrSelection.h" +#include "llvm/CodeGen/InstrScheduling.h" +#include "llvm/CodeGen/RegisterAllocation.h" +#include "llvm/CodeGen/MachineCodeForMethod.h" +#include "llvm/CodeGen/MachineCodeForInstruction.h" +#include "llvm/Reoptimizer/Mapping/MappingInfo.h" +#include "llvm/Reoptimizer/Mapping/FInfo.h" +#include "llvm/Transforms/Scalar.h" +#include "Support/CommandLine.h" +#include "llvm/PassManager.h" +#include "llvm/Function.h" #include "llvm/DerivedTypes.h" //--------------------------------------------------------------------------- +// Command line options to control choice of code generation passes. +//--------------------------------------------------------------------------- + +static cl::opt<bool> DisablePreSelect("nopreselect", + cl::desc("Disable preselection pass")); + +static cl::opt<bool> DisableSched("nosched", + cl::desc("Disable local scheduling pass")); + +//--------------------------------------------------------------------------- // class TargetMachine // // Purpose: @@ -44,6 +66,99 @@ TargetMachine::findOptimalStorageSize(const Type* ty) const } +//===---------------------------------------------------------------------===// +// Default code generation passes. +// +// Native code generation for a specified target. +//===---------------------------------------------------------------------===// + +class ConstructMachineCodeForFunction : public FunctionPass { + TargetMachine &Target; +public: + inline ConstructMachineCodeForFunction(TargetMachine &T) : Target(T) {} + + const char *getPassName() const { + return "ConstructMachineCodeForFunction"; + } + + bool runOnFunction(Function &F) { + MachineCodeForMethod::construct(&F, Target); + return false; + } +}; + +struct FreeMachineCodeForFunction : public FunctionPass { + const char *getPassName() const { return "FreeMachineCodeForFunction"; } + + static void freeMachineCode(Instruction &I) { + MachineCodeForInstruction::destroy(&I); + } + + bool runOnFunction(Function &F) { + for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) + for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I) + MachineCodeForInstruction::get(I).dropAllReferences(); + + for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) + for_each(FI->begin(), FI->end(), freeMachineCode); + + return false; + } +}; + +// addPassesToEmitAssembly - This method controls the entire code generation +// process for the ultra sparc. +// +void +TargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) +{ + // Construct and initialize the MachineCodeForMethod object for this fn. + PM.add(new ConstructMachineCodeForFunction(*this)); + + // Specialize LLVM code for this target machine and then + // run basic dataflow optimizations on LLVM code. + if (!DisablePreSelect) + { + PM.add(createPreSelectionPass(*this)); + PM.add(createReassociatePass()); + PM.add(createGCSEPass()); + PM.add(createLICMPass()); + } + + PM.add(createInstructionSelectionPass(*this)); + + if (!DisableSched) + PM.add(createInstructionSchedulingWithSSAPass(*this)); + + PM.add(getRegisterAllocator(*this)); + + //PM.add(new OptimizeLeafProcedures()); + //PM.add(new DeleteFallThroughBranches()); + //PM.add(new RemoveChainedBranches()); // should be folded with previous + //PM.add(new RemoveRedundantOps()); // operations with %g0, NOP, etc. + + PM.add(getPrologEpilogInsertionPass()); + + PM.add(MappingInfoForFunction(Out)); + + // Output assembly language to the .s file. Assembly emission is split into + // two parts: Function output and Global value output. This is because + // function output is pipelined with all of the rest of code generation stuff, + // allowing machine code representations for functions to be free'd after the + // function has been emitted. + // + PM.add(getFunctionAsmPrinterPass(Out)); + PM.add(new FreeMachineCodeForFunction()); // Free stuff no longer needed + + // Emit Module level assembly after all of the functions have been processed. + PM.add(getModuleAsmPrinterPass(Out)); + + // Emit bytecode to the assembly file into its special section next + PM.add(getEmitBytecodeToAsmPass(Out)); + PM.add(getFunctionInfo(Out)); +} + + //--------------------------------------------------------------------------- // class MachineInstructionInfo // Interface to description of machine instructions @@ -79,6 +194,10 @@ MachineInstrInfo::constantFitsInImmedField(MachineOpCode opCode, uint64_t maxImmedValue = maxImmedConstant(opCode, isSignExtended); if (maxImmedValue != 0) { + // NEED TO HANDLE UNSIGNED VALUES SINCE THEY MAY BECOME MUCH + // SMALLER AFTER CASTING TO SIGN-EXTENDED int, short, or char. + // See CreateUIntSetInstruction in SparcInstrInfo.cpp. + // Now check if the constant fits if (intValue <= (int64_t) maxImmedValue && intValue >= -((int64_t) maxImmedValue+1)) |