mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
RegAlloc superpass: includes phi elimination, coalescing, and scheduling.
Creates a configurable regalloc pipeline. Ensure specific llc options do what they say and nothing more: -reglloc=... has no effect other than selecting the allocator pass itself. This patch introduces a new umbrella flag, "-optimize-regalloc", to enable/disable the optimizing regalloc "superpass". This allows for example testing coalscing and scheduling under -O0 or vice-versa. When a CodeGen pass requires the MachineFunction to have a particular property, we need to explicitly define that property so it can be directly queried rather than naming a specific Pass. For example, to check for SSA, use MRI->isSSA, not addRequired<PHIElimination>. CodeGen transformation passes are never "required" as an analysis ProcessImplicitDefs does not require LiveVariables. We have a plan to massively simplify some of the early passes within the regalloc superpass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150226 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
16f72dd686
commit
8dd26253f5
@ -76,6 +76,8 @@ public:
|
|||||||
bool getEnableTailMerge() const { return EnableTailMerge; }
|
bool getEnableTailMerge() const { return EnableTailMerge; }
|
||||||
void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); }
|
void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); }
|
||||||
|
|
||||||
|
bool getOptimizeRegAlloc() const;
|
||||||
|
|
||||||
/// Add common target configurable passes that perform LLVM IR to IR
|
/// Add common target configurable passes that perform LLVM IR to IR
|
||||||
/// transforms following machine independent optimization.
|
/// transforms following machine independent optimization.
|
||||||
virtual void addIRPasses();
|
virtual void addIRPasses();
|
||||||
@ -122,8 +124,17 @@ protected:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// addRegAlloc - Add standard passes related to register allocation.
|
/// createTargetRegisterAllocator - Create the register allocator pass for
|
||||||
virtual void addRegAlloc();
|
/// this target at the current optimization level.
|
||||||
|
virtual FunctionPass *createTargetRegisterAllocator(bool Optimized);
|
||||||
|
|
||||||
|
/// addFastRegAlloc - Add the minimum set of target-independent passes that
|
||||||
|
/// are required for fast register allocation.
|
||||||
|
virtual void addFastRegAlloc(FunctionPass *RegAllocPass);
|
||||||
|
|
||||||
|
// addOptimizedRegAlloc - Add passes related to register allocation.
|
||||||
|
// LLVMTargetMachine provides standard regalloc passes for most targets.
|
||||||
|
virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass);
|
||||||
|
|
||||||
/// addPostRegAlloc - This method may be implemented by targets that want
|
/// addPostRegAlloc - This method may be implemented by targets that want
|
||||||
/// to run passes after register allocation but before prolog-epilog
|
/// to run passes after register allocation but before prolog-epilog
|
||||||
@ -160,6 +171,10 @@ protected:
|
|||||||
/// Add a target-independent CodeGen pass at this point in the pipeline.
|
/// Add a target-independent CodeGen pass at this point in the pipeline.
|
||||||
void addPass(char &ID);
|
void addPass(char &ID);
|
||||||
|
|
||||||
|
/// addMachinePasses helper to create the target-selected or overriden
|
||||||
|
/// regalloc pass.
|
||||||
|
FunctionPass *createRegAllocPass(bool Optimized);
|
||||||
|
|
||||||
/// printNoVerify - Add a pass to dump the machine function, if debugging is
|
/// printNoVerify - Add a pass to dump the machine function, if debugging is
|
||||||
/// enabled.
|
/// enabled.
|
||||||
///
|
///
|
||||||
@ -200,6 +215,10 @@ namespace llvm {
|
|||||||
/// EdgeBundles analysis - Bundle machine CFG edges.
|
/// EdgeBundles analysis - Bundle machine CFG edges.
|
||||||
extern char &EdgeBundlesID;
|
extern char &EdgeBundlesID;
|
||||||
|
|
||||||
|
/// LiveVariables pass - This pass computes the set of blocks in which each
|
||||||
|
/// variable is life and sets machine operand kill flags.
|
||||||
|
extern char &LiveVariablesID;
|
||||||
|
|
||||||
/// PHIElimination - This pass eliminates machine instruction PHI nodes
|
/// PHIElimination - This pass eliminates machine instruction PHI nodes
|
||||||
/// by inserting copy instructions. This destroys SSA information, but is the
|
/// by inserting copy instructions. This destroys SSA information, but is the
|
||||||
/// desired input for some register allocators. This pass is "required" by
|
/// desired input for some register allocators. This pass is "required" by
|
||||||
@ -222,8 +241,11 @@ namespace llvm {
|
|||||||
/// register allocators.
|
/// register allocators.
|
||||||
extern char &TwoAddressInstructionPassID;
|
extern char &TwoAddressInstructionPassID;
|
||||||
|
|
||||||
/// RegisteCoalescer - This pass merges live ranges to eliminate copies.
|
/// ProcessImpicitDefs pass - This pass removes IMPLICIT_DEFs.
|
||||||
extern char &RegisterCoalescerPassID;
|
extern char &ProcessImplicitDefsID;
|
||||||
|
|
||||||
|
/// RegisterCoalescer - This pass merges live ranges to eliminate copies.
|
||||||
|
extern char &RegisterCoalescerID;
|
||||||
|
|
||||||
/// MachineScheduler - This pass schedules machine instructions.
|
/// MachineScheduler - This pass schedules machine instructions.
|
||||||
extern char &MachineSchedulerID;
|
extern char &MachineSchedulerID;
|
||||||
@ -239,11 +261,6 @@ namespace llvm {
|
|||||||
/// DeadMachineInstructionElim - This pass removes dead machine instructions.
|
/// DeadMachineInstructionElim - This pass removes dead machine instructions.
|
||||||
extern char &DeadMachineInstructionElimID;
|
extern char &DeadMachineInstructionElimID;
|
||||||
|
|
||||||
/// Creates a register allocator as the user specified on the command line, or
|
|
||||||
/// picks one that matches OptLevel.
|
|
||||||
///
|
|
||||||
FunctionPass *createRegisterAllocator(CodeGenOpt::Level OptLevel);
|
|
||||||
|
|
||||||
/// FastRegisterAllocation Pass - This pass register allocates as fast as
|
/// FastRegisterAllocation Pass - This pass register allocates as fast as
|
||||||
/// possible. It is best suited for debug code where live ranges are short.
|
/// possible. It is best suited for debug code where live ranges are short.
|
||||||
///
|
///
|
||||||
|
@ -30,10 +30,6 @@ namespace llvm {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// StrongPHIElim - This flag enables more aggressive PHI elimination
|
|
||||||
/// wth earlier copy coalescing.
|
|
||||||
extern bool StrongPHIElim;
|
|
||||||
|
|
||||||
class TargetOptions {
|
class TargetOptions {
|
||||||
public:
|
public:
|
||||||
TargetOptions()
|
TargetOptions()
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "llvm/CodeGen/MachineLoopInfo.h"
|
#include "llvm/CodeGen/MachineLoopInfo.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/Passes.h"
|
#include "llvm/CodeGen/Passes.h"
|
||||||
#include "llvm/CodeGen/ProcessImplicitDefs.h"
|
|
||||||
#include "llvm/Target/TargetRegisterInfo.h"
|
#include "llvm/Target/TargetRegisterInfo.h"
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
@ -48,13 +47,11 @@ STATISTIC(numIntervals , "Number of original intervals");
|
|||||||
char LiveIntervals::ID = 0;
|
char LiveIntervals::ID = 0;
|
||||||
INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals",
|
INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals",
|
||||||
"Live Interval Analysis", false, false)
|
"Live Interval Analysis", false, false)
|
||||||
|
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
|
||||||
INITIALIZE_PASS_DEPENDENCY(LiveVariables)
|
INITIALIZE_PASS_DEPENDENCY(LiveVariables)
|
||||||
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
|
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
|
||||||
INITIALIZE_PASS_DEPENDENCY(PHIElimination)
|
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
|
||||||
INITIALIZE_PASS_DEPENDENCY(TwoAddressInstructionPass)
|
|
||||||
INITIALIZE_PASS_DEPENDENCY(ProcessImplicitDefs)
|
|
||||||
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
||||||
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
|
|
||||||
INITIALIZE_PASS_END(LiveIntervals, "liveintervals",
|
INITIALIZE_PASS_END(LiveIntervals, "liveintervals",
|
||||||
"Live Interval Analysis", false, false)
|
"Live Interval Analysis", false, false)
|
||||||
|
|
||||||
@ -67,15 +64,6 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
AU.addRequired<MachineLoopInfo>();
|
AU.addRequired<MachineLoopInfo>();
|
||||||
AU.addPreserved<MachineLoopInfo>();
|
AU.addPreserved<MachineLoopInfo>();
|
||||||
AU.addPreservedID(MachineDominatorsID);
|
AU.addPreservedID(MachineDominatorsID);
|
||||||
|
|
||||||
if (!StrongPHIElim) {
|
|
||||||
AU.addPreservedID(PHIEliminationID);
|
|
||||||
AU.addRequiredID(PHIEliminationID);
|
|
||||||
}
|
|
||||||
|
|
||||||
AU.addRequiredID(TwoAddressInstructionPassID);
|
|
||||||
AU.addPreserved<ProcessImplicitDefs>();
|
|
||||||
AU.addRequired<ProcessImplicitDefs>();
|
|
||||||
AU.addPreserved<SlotIndexes>();
|
AU.addPreserved<SlotIndexes>();
|
||||||
AU.addRequiredTransitive<SlotIndexes>();
|
AU.addRequiredTransitive<SlotIndexes>();
|
||||||
MachineFunctionPass::getAnalysisUsage(AU);
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/ADT/DepthFirstIterator.h"
|
#include "llvm/ADT/DepthFirstIterator.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
@ -41,6 +42,7 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
char LiveVariables::ID = 0;
|
char LiveVariables::ID = 0;
|
||||||
|
char &llvm::LiveVariablesID = LiveVariables::ID;
|
||||||
INITIALIZE_PASS_BEGIN(LiveVariables, "livevars",
|
INITIALIZE_PASS_BEGIN(LiveVariables, "livevars",
|
||||||
"Live Variable Analysis", false, false)
|
"Live Variable Analysis", false, false)
|
||||||
INITIALIZE_PASS_DEPENDENCY(UnreachableMachineBlockElim)
|
INITIALIZE_PASS_DEPENDENCY(UnreachableMachineBlockElim)
|
||||||
@ -511,6 +513,12 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
std::fill(PhysRegUse, PhysRegUse + NumRegs, (MachineInstr*)0);
|
std::fill(PhysRegUse, PhysRegUse + NumRegs, (MachineInstr*)0);
|
||||||
PHIJoins.clear();
|
PHIJoins.clear();
|
||||||
|
|
||||||
|
// FIXME: LiveIntervals will be updated to remove its dependence on
|
||||||
|
// LiveVariables to improve compilation time and eliminate bizarre pass
|
||||||
|
// dependencies. Until then, we can't change much in -O0.
|
||||||
|
if (!MRI->isSSA())
|
||||||
|
report_fatal_error("regalloc=... not currently supported with -O0");
|
||||||
|
|
||||||
analyzePHINodes(mf);
|
analyzePHINodes(mf);
|
||||||
|
|
||||||
// Calculate live variable information in depth first order on the CFG of the
|
// Calculate live variable information in depth first order on the CFG of the
|
||||||
|
@ -69,8 +69,6 @@ INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
|
|||||||
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
||||||
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
|
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
|
||||||
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
|
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
|
||||||
INITIALIZE_PASS_DEPENDENCY(StrongPHIElimination)
|
|
||||||
INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer)
|
|
||||||
INITIALIZE_PASS_END(MachineScheduler, "misched",
|
INITIALIZE_PASS_END(MachineScheduler, "misched",
|
||||||
"Machine Instruction Scheduler", false, false)
|
"Machine Instruction Scheduler", false, false)
|
||||||
|
|
||||||
@ -91,12 +89,6 @@ void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
AU.addPreserved<LiveIntervals>();
|
AU.addPreserved<LiveIntervals>();
|
||||||
AU.addRequired<LiveDebugVariables>();
|
AU.addRequired<LiveDebugVariables>();
|
||||||
AU.addPreserved<LiveDebugVariables>();
|
AU.addPreserved<LiveDebugVariables>();
|
||||||
if (StrongPHIElim) {
|
|
||||||
AU.addRequiredID(StrongPHIEliminationID);
|
|
||||||
AU.addPreservedID(StrongPHIEliminationID);
|
|
||||||
}
|
|
||||||
AU.addRequiredID(RegisterCoalescerPassID);
|
|
||||||
AU.addPreservedID(RegisterCoalescerPassID);
|
|
||||||
MachineFunctionPass::getAnalysisUsage(AU);
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,11 +92,15 @@ STATISTIC(NumCriticalEdgesSplit, "Number of critical edges split");
|
|||||||
STATISTIC(NumReused, "Number of reused lowered phis");
|
STATISTIC(NumReused, "Number of reused lowered phis");
|
||||||
|
|
||||||
char PHIElimination::ID = 0;
|
char PHIElimination::ID = 0;
|
||||||
INITIALIZE_PASS(PHIElimination, "phi-node-elimination",
|
|
||||||
"Eliminate PHI nodes for register allocation", false, false)
|
|
||||||
|
|
||||||
char& llvm::PHIEliminationID = PHIElimination::ID;
|
char& llvm::PHIEliminationID = PHIElimination::ID;
|
||||||
|
|
||||||
|
INITIALIZE_PASS_BEGIN(PHIElimination, "phi-node-elimination",
|
||||||
|
"Eliminate PHI nodes for register allocation",
|
||||||
|
false, false)
|
||||||
|
INITIALIZE_PASS_DEPENDENCY(LiveVariables)
|
||||||
|
INITIALIZE_PASS_END(PHIElimination, "phi-node-elimination",
|
||||||
|
"Eliminate PHI nodes for register allocation", false, false)
|
||||||
|
|
||||||
void PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const {
|
void PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.addPreserved<LiveVariables>();
|
AU.addPreserved<LiveVariables>();
|
||||||
AU.addPreserved<MachineDominatorTree>();
|
AU.addPreserved<MachineDominatorTree>();
|
||||||
|
@ -51,6 +51,13 @@ static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
|
|||||||
cl::desc("Disable Machine LICM"));
|
cl::desc("Disable Machine LICM"));
|
||||||
static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
|
static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
|
||||||
cl::desc("Disable Machine Common Subexpression Elimination"));
|
cl::desc("Disable Machine Common Subexpression Elimination"));
|
||||||
|
static cl::opt<cl::boolOrDefault>
|
||||||
|
OptimizeRegAlloc("optimize-regalloc", cl::Hidden,
|
||||||
|
cl::desc("Enable optimized register allocation compilation path."));
|
||||||
|
static cl::opt<bool> EnableMachineSched("enable-misched", cl::Hidden,
|
||||||
|
cl::desc("Enable the machine instruction scheduling pass."));
|
||||||
|
static cl::opt<bool> EnableStrongPHIElim("strong-phi-elim", cl::Hidden,
|
||||||
|
cl::desc("Use strong PHI elimination."));
|
||||||
static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm",
|
static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm",
|
||||||
cl::Hidden,
|
cl::Hidden,
|
||||||
cl::desc("Disable Machine LICM"));
|
cl::desc("Disable Machine LICM"));
|
||||||
@ -225,7 +232,10 @@ void TargetPassConfig::addMachinePasses() {
|
|||||||
|
|
||||||
// Run register allocation and passes that are tightly coupled with it,
|
// Run register allocation and passes that are tightly coupled with it,
|
||||||
// including phi elimination and scheduling.
|
// including phi elimination and scheduling.
|
||||||
addRegAlloc();
|
if (getOptimizeRegAlloc())
|
||||||
|
addOptimizedRegAlloc(createRegAllocPass(true));
|
||||||
|
else
|
||||||
|
addFastRegAlloc(createRegAllocPass(false));
|
||||||
|
|
||||||
// Run post-ra passes.
|
// Run post-ra passes.
|
||||||
if (addPostRegAlloc())
|
if (addPostRegAlloc())
|
||||||
@ -306,58 +316,126 @@ void TargetPassConfig::addMachineSSAOptimization() {
|
|||||||
/// Register Allocation Pass Configuration
|
/// Register Allocation Pass Configuration
|
||||||
//===---------------------------------------------------------------------===//
|
//===---------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
bool TargetPassConfig::getOptimizeRegAlloc() const {
|
||||||
|
switch (OptimizeRegAlloc) {
|
||||||
|
case cl::BOU_UNSET: return getOptLevel() != CodeGenOpt::None;
|
||||||
|
case cl::BOU_TRUE: return true;
|
||||||
|
case cl::BOU_FALSE: return false;
|
||||||
|
}
|
||||||
|
llvm_unreachable("Invalid optimize-regalloc state");
|
||||||
|
}
|
||||||
|
|
||||||
/// RegisterRegAlloc's global Registry tracks allocator registration.
|
/// RegisterRegAlloc's global Registry tracks allocator registration.
|
||||||
MachinePassRegistry RegisterRegAlloc::Registry;
|
MachinePassRegistry RegisterRegAlloc::Registry;
|
||||||
|
|
||||||
/// A dummy default pass factory indicates whether the register allocator is
|
/// A dummy default pass factory indicates whether the register allocator is
|
||||||
/// overridden on the command line.
|
/// overridden on the command line.
|
||||||
static FunctionPass *createDefaultRegisterAllocator() { return 0; }
|
static FunctionPass *useDefaultRegisterAllocator() { return 0; }
|
||||||
static RegisterRegAlloc
|
static RegisterRegAlloc
|
||||||
defaultRegAlloc("default",
|
defaultRegAlloc("default",
|
||||||
"pick register allocator based on -O option",
|
"pick register allocator based on -O option",
|
||||||
createDefaultRegisterAllocator);
|
useDefaultRegisterAllocator);
|
||||||
|
|
||||||
/// -regalloc=... command line option.
|
/// -regalloc=... command line option.
|
||||||
static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
|
static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
|
||||||
RegisterPassParser<RegisterRegAlloc> >
|
RegisterPassParser<RegisterRegAlloc> >
|
||||||
RegAlloc("regalloc",
|
RegAlloc("regalloc",
|
||||||
cl::init(&createDefaultRegisterAllocator),
|
cl::init(&useDefaultRegisterAllocator),
|
||||||
cl::desc("Register allocator to use"));
|
cl::desc("Register allocator to use"));
|
||||||
|
|
||||||
|
|
||||||
/// createRegisterAllocator - choose the appropriate register allocator.
|
/// Instantiate the default register allocator pass for this target for either
|
||||||
FunctionPass *llvm::createRegisterAllocator(CodeGenOpt::Level OptLevel) {
|
/// the optimized or unoptimized allocation path. This will be added to the pass
|
||||||
|
/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
|
||||||
|
/// in the optimized case.
|
||||||
|
///
|
||||||
|
/// A target that uses the standard regalloc pass order for fast or optimized
|
||||||
|
/// allocation may still override this for per-target regalloc
|
||||||
|
/// selection. But -regalloc=... always takes precedence.
|
||||||
|
FunctionPass *TargetPassConfig::createTargetRegisterAllocator(bool Optimized) {
|
||||||
|
if (Optimized)
|
||||||
|
return createGreedyRegisterAllocator();
|
||||||
|
else
|
||||||
|
return createFastRegisterAllocator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find and instantiate the register allocation pass requested by this target
|
||||||
|
/// at the current optimization level. Different register allocators are
|
||||||
|
/// defined as separate passes because they may require different analysis.
|
||||||
|
///
|
||||||
|
/// This helper ensures that the regalloc= option is always available,
|
||||||
|
/// even for targets that override the default allocator.
|
||||||
|
///
|
||||||
|
/// FIXME: When MachinePassRegistry register pass IDs instead of function ptrs,
|
||||||
|
/// this can be folded into addPass.
|
||||||
|
FunctionPass *TargetPassConfig::createRegAllocPass(bool Optimized) {
|
||||||
RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
|
RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
|
||||||
|
|
||||||
|
// Initialize the global default.
|
||||||
if (!Ctor) {
|
if (!Ctor) {
|
||||||
Ctor = RegAlloc;
|
Ctor = RegAlloc;
|
||||||
RegisterRegAlloc::setDefault(RegAlloc);
|
RegisterRegAlloc::setDefault(RegAlloc);
|
||||||
}
|
}
|
||||||
|
if (Ctor != useDefaultRegisterAllocator)
|
||||||
if (Ctor != createDefaultRegisterAllocator)
|
|
||||||
return Ctor();
|
return Ctor();
|
||||||
|
|
||||||
// When the 'default' allocator is requested, pick one based on OptLevel.
|
// With no -regalloc= override, ask the target for a regalloc pass.
|
||||||
switch (OptLevel) {
|
return createTargetRegisterAllocator(Optimized);
|
||||||
case CodeGenOpt::None:
|
}
|
||||||
return createFastRegisterAllocator();
|
|
||||||
default:
|
/// Add the minimum set of target-independent passes that are required for
|
||||||
return createGreedyRegisterAllocator();
|
/// register allocation. No coalescing or scheduling.
|
||||||
}
|
void TargetPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
|
||||||
|
addPass(PHIEliminationID);
|
||||||
|
addPass(TwoAddressInstructionPassID);
|
||||||
|
|
||||||
|
PM.add(RegAllocPass);
|
||||||
|
printAndVerify("After Register Allocation");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add standard target-independent passes that are tightly coupled with
|
/// Add standard target-independent passes that are tightly coupled with
|
||||||
/// register allocation, including coalescing, machine instruction scheduling,
|
/// optimized register allocation, including coalescing, machine instruction
|
||||||
/// and register allocation itself.
|
/// scheduling, and register allocation itself.
|
||||||
///
|
void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
|
||||||
/// FIXME: This will become the register allocation "super pass" pipeline.
|
// LiveVariables currently requires pure SSA form.
|
||||||
void TargetPassConfig::addRegAlloc() {
|
//
|
||||||
// Perform register allocation.
|
// FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
|
||||||
PM.add(createRegisterAllocator(getOptLevel()));
|
// LiveVariables can be removed completely, and LiveIntervals can be directly
|
||||||
|
// computed. (We still either need to regenerate kill flags after regalloc, or
|
||||||
|
// preferably fix the scavenger to not depend on them).
|
||||||
|
addPass(LiveVariablesID);
|
||||||
|
|
||||||
|
// Add passes that move from transformed SSA into conventional SSA. This is a
|
||||||
|
// "copy coalescing" problem.
|
||||||
|
//
|
||||||
|
if (!EnableStrongPHIElim) {
|
||||||
|
// Edge splitting is smarter with machine loop info.
|
||||||
|
addPass(MachineLoopInfoID);
|
||||||
|
addPass(PHIEliminationID);
|
||||||
|
}
|
||||||
|
addPass(TwoAddressInstructionPassID);
|
||||||
|
|
||||||
|
// FIXME: Either remove this pass completely, or fix it so that it works on
|
||||||
|
// SSA form. We could modify LiveIntervals to be independent of this pass, But
|
||||||
|
// it would be even better to simply eliminate *all* IMPLICIT_DEFs before
|
||||||
|
// leaving SSA.
|
||||||
|
addPass(ProcessImplicitDefsID);
|
||||||
|
|
||||||
|
if (EnableStrongPHIElim)
|
||||||
|
addPass(StrongPHIEliminationID);
|
||||||
|
|
||||||
|
addPass(RegisterCoalescerID);
|
||||||
|
|
||||||
|
// PreRA instruction scheduling.
|
||||||
|
if (EnableMachineSched)
|
||||||
|
addPass(MachineSchedulerID);
|
||||||
|
|
||||||
|
// Add the selected register allocation pass.
|
||||||
|
PM.add(RegAllocPass);
|
||||||
printAndVerify("After Register Allocation");
|
printAndVerify("After Register Allocation");
|
||||||
|
|
||||||
// Perform stack slot coloring and post-ra machine LICM.
|
// Perform stack slot coloring and post-ra machine LICM.
|
||||||
if (getOptLevel() != CodeGenOpt::None) {
|
//
|
||||||
// FIXME: Re-enable coloring with register when it's capable of adding
|
// FIXME: Re-enable coloring with register when it's capable of adding
|
||||||
// kill markers.
|
// kill markers.
|
||||||
if (!DisableSSC)
|
if (!DisableSSC)
|
||||||
@ -370,7 +448,6 @@ void TargetPassConfig::addRegAlloc() {
|
|||||||
addPass(MachineLICMID);
|
addPass(MachineLICMID);
|
||||||
|
|
||||||
printAndVerify("After StackSlotColoring and postra Machine LICM");
|
printAndVerify("After StackSlotColoring and postra Machine LICM");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===---------------------------------------------------------------------===//
|
//===---------------------------------------------------------------------===//
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
char ProcessImplicitDefs::ID = 0;
|
char ProcessImplicitDefs::ID = 0;
|
||||||
|
char &llvm::ProcessImplicitDefsID = ProcessImplicitDefs::ID;
|
||||||
|
|
||||||
INITIALIZE_PASS_BEGIN(ProcessImplicitDefs, "processimpdefs",
|
INITIALIZE_PASS_BEGIN(ProcessImplicitDefs, "processimpdefs",
|
||||||
"Process Implicit Definitions", false, false)
|
"Process Implicit Definitions", false, false)
|
||||||
INITIALIZE_PASS_DEPENDENCY(LiveVariables)
|
INITIALIZE_PASS_DEPENDENCY(LiveVariables)
|
||||||
@ -36,7 +38,6 @@ void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
AU.setPreservesCFG();
|
AU.setPreservesCFG();
|
||||||
AU.addPreserved<AliasAnalysis>();
|
AU.addPreserved<AliasAnalysis>();
|
||||||
AU.addPreserved<LiveVariables>();
|
AU.addPreserved<LiveVariables>();
|
||||||
AU.addRequired<LiveVariables>();
|
|
||||||
AU.addPreservedID(MachineLoopInfoID);
|
AU.addPreservedID(MachineLoopInfoID);
|
||||||
AU.addPreservedID(MachineDominatorsID);
|
AU.addPreservedID(MachineDominatorsID);
|
||||||
AU.addPreservedID(TwoAddressInstructionPassID);
|
AU.addPreservedID(TwoAddressInstructionPassID);
|
||||||
@ -87,7 +88,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
TII = fn.getTarget().getInstrInfo();
|
TII = fn.getTarget().getInstrInfo();
|
||||||
TRI = fn.getTarget().getRegisterInfo();
|
TRI = fn.getTarget().getRegisterInfo();
|
||||||
MRI = &fn.getRegInfo();
|
MRI = &fn.getRegInfo();
|
||||||
LV = &getAnalysis<LiveVariables>();
|
LV = getAnalysisIfAvailable<LiveVariables>();
|
||||||
|
|
||||||
SmallSet<unsigned, 8> ImpDefRegs;
|
SmallSet<unsigned, 8> ImpDefRegs;
|
||||||
SmallVector<MachineInstr*, 8> ImpDefMIs;
|
SmallVector<MachineInstr*, 8> ImpDefMIs;
|
||||||
@ -122,7 +123,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
if (MI->isCopy() && MI->getOperand(0).readsReg()) {
|
if (MI->isCopy() && MI->getOperand(0).readsReg()) {
|
||||||
MachineOperand &MO = MI->getOperand(1);
|
MachineOperand &MO = MI->getOperand(1);
|
||||||
if (MO.isUndef() || ImpDefRegs.count(MO.getReg())) {
|
if (MO.isUndef() || ImpDefRegs.count(MO.getReg())) {
|
||||||
if (MO.isKill()) {
|
if (LV && MO.isKill()) {
|
||||||
LiveVariables::VarInfo& vi = LV->getVarInfo(MO.getReg());
|
LiveVariables::VarInfo& vi = LV->getVarInfo(MO.getReg());
|
||||||
vi.removeKill(MI);
|
vi.removeKill(MI);
|
||||||
}
|
}
|
||||||
@ -156,9 +157,11 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
MI->RemoveOperand(j);
|
MI->RemoveOperand(j);
|
||||||
if (isKill) {
|
if (isKill) {
|
||||||
ImpDefRegs.erase(Reg);
|
ImpDefRegs.erase(Reg);
|
||||||
|
if (LV) {
|
||||||
LiveVariables::VarInfo& vi = LV->getVarInfo(Reg);
|
LiveVariables::VarInfo& vi = LV->getVarInfo(Reg);
|
||||||
vi.removeKill(MI);
|
vi.removeKill(MI);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ChangedToImpDef = true;
|
ChangedToImpDef = true;
|
||||||
Changed = true;
|
Changed = true;
|
||||||
break;
|
break;
|
||||||
@ -266,7 +269,7 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update LiveVariables varinfo if the instruction is a kill.
|
// Update LiveVariables varinfo if the instruction is a kill.
|
||||||
if (isKill) {
|
if (LV && isKill) {
|
||||||
LiveVariables::VarInfo& vi = LV->getVarInfo(Reg);
|
LiveVariables::VarInfo& vi = LV->getVarInfo(Reg);
|
||||||
vi.removeKill(RMI);
|
vi.removeKill(RMI);
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,6 @@ RABasic::RABasic(): MachineFunctionPass(ID) {
|
|||||||
initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry());
|
initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry());
|
||||||
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
||||||
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
||||||
initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry());
|
|
||||||
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
||||||
initializeMachineSchedulerPass(*PassRegistry::getPassRegistry());
|
initializeMachineSchedulerPass(*PassRegistry::getPassRegistry());
|
||||||
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
||||||
@ -151,9 +150,6 @@ void RABasic::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
AU.addPreserved<SlotIndexes>();
|
AU.addPreserved<SlotIndexes>();
|
||||||
AU.addRequired<LiveDebugVariables>();
|
AU.addRequired<LiveDebugVariables>();
|
||||||
AU.addPreserved<LiveDebugVariables>();
|
AU.addPreserved<LiveDebugVariables>();
|
||||||
if (StrongPHIElim)
|
|
||||||
AU.addRequiredID(StrongPHIEliminationID);
|
|
||||||
AU.addRequiredTransitiveID(RegisterCoalescerPassID);
|
|
||||||
AU.addRequired<CalculateSpillWeights>();
|
AU.addRequired<CalculateSpillWeights>();
|
||||||
AU.addRequired<LiveStacks>();
|
AU.addRequired<LiveStacks>();
|
||||||
AU.addPreserved<LiveStacks>();
|
AU.addPreserved<LiveStacks>();
|
||||||
|
@ -49,10 +49,7 @@ namespace {
|
|||||||
public:
|
public:
|
||||||
static char ID;
|
static char ID;
|
||||||
RAFast() : MachineFunctionPass(ID), StackSlotForVirtReg(-1),
|
RAFast() : MachineFunctionPass(ID), StackSlotForVirtReg(-1),
|
||||||
isBulkSpilling(false) {
|
isBulkSpilling(false) {}
|
||||||
initializePHIEliminationPass(*PassRegistry::getPassRegistry());
|
|
||||||
initializeTwoAddressInstructionPassPass(*PassRegistry::getPassRegistry());
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
const TargetMachine *TM;
|
const TargetMachine *TM;
|
||||||
MachineFunction *MF;
|
MachineFunction *MF;
|
||||||
@ -137,8 +134,6 @@ namespace {
|
|||||||
|
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.setPreservesCFG();
|
AU.setPreservesCFG();
|
||||||
AU.addRequiredID(PHIEliminationID);
|
|
||||||
AU.addRequiredID(TwoAddressInstructionPassID);
|
|
||||||
MachineFunctionPass::getAnalysisUsage(AU);
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1089,6 +1084,8 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) {
|
|||||||
RegClassInfo.runOnMachineFunction(Fn);
|
RegClassInfo.runOnMachineFunction(Fn);
|
||||||
UsedInInstr.resize(TRI->getNumRegs());
|
UsedInInstr.resize(TRI->getNumRegs());
|
||||||
|
|
||||||
|
assert(!MRI->isSSA() && "regalloc requires leaving SSA");
|
||||||
|
|
||||||
// initialize the virtual->physical register map to have a 'null'
|
// initialize the virtual->physical register map to have a 'null'
|
||||||
// mapping for all virtual registers
|
// mapping for all virtual registers
|
||||||
StackSlotForVirtReg.resize(MRI->getNumVirtRegs());
|
StackSlotForVirtReg.resize(MRI->getNumVirtRegs());
|
||||||
|
@ -51,13 +51,6 @@ STATISTIC(NumGlobalSplits, "Number of split global live ranges");
|
|||||||
STATISTIC(NumLocalSplits, "Number of split local live ranges");
|
STATISTIC(NumLocalSplits, "Number of split local live ranges");
|
||||||
STATISTIC(NumEvicted, "Number of interferences evicted");
|
STATISTIC(NumEvicted, "Number of interferences evicted");
|
||||||
|
|
||||||
/// EnableMachineSched - temporary flag to enable the machine scheduling pass
|
|
||||||
/// until we complete the register allocation pass configuration cleanup.
|
|
||||||
static cl::opt<bool>
|
|
||||||
EnableMachineSched("enable-misched",
|
|
||||||
cl::desc("Enable the machine instruction scheduling pass."),
|
|
||||||
cl::init(false), cl::Hidden);
|
|
||||||
|
|
||||||
static cl::opt<SplitEditor::ComplementSpillMode>
|
static cl::opt<SplitEditor::ComplementSpillMode>
|
||||||
SplitSpillMode("split-spill-mode", cl::Hidden,
|
SplitSpillMode("split-spill-mode", cl::Hidden,
|
||||||
cl::desc("Spill mode for splitting live ranges"),
|
cl::desc("Spill mode for splitting live ranges"),
|
||||||
@ -327,7 +320,6 @@ RAGreedy::RAGreedy(): MachineFunctionPass(ID) {
|
|||||||
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
||||||
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
||||||
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
||||||
initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry());
|
|
||||||
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
||||||
initializeMachineSchedulerPass(*PassRegistry::getPassRegistry());
|
initializeMachineSchedulerPass(*PassRegistry::getPassRegistry());
|
||||||
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
||||||
@ -348,11 +340,6 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
AU.addPreserved<SlotIndexes>();
|
AU.addPreserved<SlotIndexes>();
|
||||||
AU.addRequired<LiveDebugVariables>();
|
AU.addRequired<LiveDebugVariables>();
|
||||||
AU.addPreserved<LiveDebugVariables>();
|
AU.addPreserved<LiveDebugVariables>();
|
||||||
if (StrongPHIElim)
|
|
||||||
AU.addRequiredID(StrongPHIEliminationID);
|
|
||||||
AU.addRequiredTransitiveID(RegisterCoalescerPassID);
|
|
||||||
if (EnableMachineSched)
|
|
||||||
AU.addRequiredID(MachineSchedulerID);
|
|
||||||
AU.addRequired<CalculateSpillWeights>();
|
AU.addRequired<CalculateSpillWeights>();
|
||||||
AU.addRequired<LiveStacks>();
|
AU.addRequired<LiveStacks>();
|
||||||
AU.addPreserved<LiveStacks>();
|
AU.addPreserved<LiveStacks>();
|
||||||
|
@ -85,7 +85,6 @@ public:
|
|||||||
: MachineFunctionPass(ID), builder(b), customPassID(cPassID) {
|
: MachineFunctionPass(ID), builder(b), customPassID(cPassID) {
|
||||||
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
||||||
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
||||||
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
|
||||||
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
||||||
initializeLiveStacksPass(*PassRegistry::getPassRegistry());
|
initializeLiveStacksPass(*PassRegistry::getPassRegistry());
|
||||||
initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
|
initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
|
||||||
@ -446,7 +445,6 @@ void RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const {
|
|||||||
au.addPreserved<SlotIndexes>();
|
au.addPreserved<SlotIndexes>();
|
||||||
au.addRequired<LiveIntervals>();
|
au.addRequired<LiveIntervals>();
|
||||||
//au.addRequiredID(SplitCriticalEdgesID);
|
//au.addRequiredID(SplitCriticalEdgesID);
|
||||||
au.addRequiredID(RegisterCoalescerPassID);
|
|
||||||
if (customPassID)
|
if (customPassID)
|
||||||
au.addRequiredID(*customPassID);
|
au.addRequiredID(*customPassID);
|
||||||
au.addRequired<CalculateSpillWeights>();
|
au.addRequired<CalculateSpillWeights>();
|
||||||
|
@ -193,7 +193,7 @@ namespace {
|
|||||||
};
|
};
|
||||||
} /// end anonymous namespace
|
} /// end anonymous namespace
|
||||||
|
|
||||||
char &llvm::RegisterCoalescerPassID = RegisterCoalescer::ID;
|
char &llvm::RegisterCoalescerID = RegisterCoalescer::ID;
|
||||||
|
|
||||||
INITIALIZE_PASS_BEGIN(RegisterCoalescer, "simple-register-coalescing",
|
INITIALIZE_PASS_BEGIN(RegisterCoalescer, "simple-register-coalescing",
|
||||||
"Simple Register Coalescing", false, false)
|
"Simple Register Coalescing", false, false)
|
||||||
@ -201,9 +201,6 @@ INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
|
|||||||
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
|
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
|
||||||
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
||||||
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
|
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
|
||||||
INITIALIZE_PASS_DEPENDENCY(StrongPHIElimination)
|
|
||||||
INITIALIZE_PASS_DEPENDENCY(PHIElimination)
|
|
||||||
INITIALIZE_PASS_DEPENDENCY(TwoAddressInstructionPass)
|
|
||||||
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
|
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
|
||||||
INITIALIZE_PASS_END(RegisterCoalescer, "simple-register-coalescing",
|
INITIALIZE_PASS_END(RegisterCoalescer, "simple-register-coalescing",
|
||||||
"Simple Register Coalescing", false, false)
|
"Simple Register Coalescing", false, false)
|
||||||
@ -375,9 +372,6 @@ void RegisterCoalescer::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
AU.addRequired<MachineLoopInfo>();
|
AU.addRequired<MachineLoopInfo>();
|
||||||
AU.addPreserved<MachineLoopInfo>();
|
AU.addPreserved<MachineLoopInfo>();
|
||||||
AU.addPreservedID(MachineDominatorsID);
|
AU.addPreservedID(MachineDominatorsID);
|
||||||
AU.addPreservedID(StrongPHIEliminationID);
|
|
||||||
AU.addPreservedID(PHIEliminationID);
|
|
||||||
AU.addPreservedID(TwoAddressInstructionPassID);
|
|
||||||
MachineFunctionPass::getAnalysisUsage(AU);
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,6 @@ namespace {
|
|||||||
AU.addPreserved<LiveVariables>();
|
AU.addPreserved<LiveVariables>();
|
||||||
AU.addPreservedID(MachineLoopInfoID);
|
AU.addPreservedID(MachineLoopInfoID);
|
||||||
AU.addPreservedID(MachineDominatorsID);
|
AU.addPreservedID(MachineDominatorsID);
|
||||||
AU.addPreservedID(PHIEliminationID);
|
|
||||||
MachineFunctionPass::getAnalysisUsage(AU);
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,10 +24,7 @@ namespace {
|
|||||||
class PTXRegAlloc : public MachineFunctionPass {
|
class PTXRegAlloc : public MachineFunctionPass {
|
||||||
public:
|
public:
|
||||||
static char ID;
|
static char ID;
|
||||||
PTXRegAlloc() : MachineFunctionPass(ID) {
|
PTXRegAlloc() : MachineFunctionPass(ID) {}
|
||||||
initializePHIEliminationPass(*PassRegistry::getPassRegistry());
|
|
||||||
initializeTwoAddressInstructionPassPass(*PassRegistry::getPassRegistry());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const char* getPassName() const {
|
virtual const char* getPassName() const {
|
||||||
return "PTX Register Allocator";
|
return "PTX Register Allocator";
|
||||||
@ -35,8 +32,6 @@ namespace {
|
|||||||
|
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.setPreservesCFG();
|
AU.setPreservesCFG();
|
||||||
AU.addRequiredID(PHIEliminationID);
|
|
||||||
AU.addRequiredID(TwoAddressInstructionPassID);
|
|
||||||
MachineFunctionPass::getAnalysisUsage(AU);
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,6 +319,8 @@ bool PTXPassConfig::addCodeGenPasses(MCContext *&OutContext) {
|
|||||||
printAndVerify("After PreRegAlloc passes");
|
printAndVerify("After PreRegAlloc passes");
|
||||||
|
|
||||||
// Perform register allocation.
|
// Perform register allocation.
|
||||||
|
addPass(PHIEliminationID);
|
||||||
|
addPass(TwoAddressInstructionPassID);
|
||||||
PM.add(createPTXRegisterAllocator());
|
PM.add(createPTXRegisterAllocator());
|
||||||
printAndVerify("After Register Allocation");
|
printAndVerify("After Register Allocation");
|
||||||
|
|
||||||
|
@ -22,8 +22,6 @@ using namespace llvm;
|
|||||||
//
|
//
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
bool StrongPHIElim;
|
|
||||||
bool EnableMachineSched;
|
|
||||||
bool HasDivModLibcall;
|
bool HasDivModLibcall;
|
||||||
bool AsmVerbosityDefault(false);
|
bool AsmVerbosityDefault(false);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=arm -mattr=+neon -O0 -regalloc=basic
|
; RUN: llc < %s -march=arm -mattr=+neon -O0 -optimize-regalloc -regalloc=basic
|
||||||
|
|
||||||
; This test would crash the rewriter when trying to handle a spill after one of
|
; This test would crash the rewriter when trying to handle a spill after one of
|
||||||
; the @llvm.arm.neon.vld3.v8i8 defined three parts of a register.
|
; the @llvm.arm.neon.vld3.v8i8 defined three parts of a register.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc -O0 -regalloc=basic < %s
|
; RUN: llc -O0 -optimize-regalloc -regalloc=basic < %s
|
||||||
; This isn't exactly a useful set of command-line options, but check that it
|
; This isn't exactly a useful set of command-line options, but check that it
|
||||||
; doesn't crash. (It was crashing because a register was getting redefined.)
|
; doesn't crash. (It was crashing because a register was getting redefined.)
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=x86 -O0 -fast-isel=false -regalloc=basic | grep mov | count 5
|
; RUN: llc < %s -march=x86 -O0 -fast-isel=false -optimize-regalloc -regalloc=basic | grep mov | count 5
|
||||||
; PR2343
|
; PR2343
|
||||||
|
|
||||||
%llvm.dbg.anchor.type = type { i32, i32 }
|
%llvm.dbg.anchor.type = type { i32, i32 }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -O0 -regalloc=basic -march=x86-64 -mattr=+mmx,+sse2 | FileCheck %s
|
; RUN: llc < %s -O0 -march=x86-64 -mattr=+mmx,+sse2 | FileCheck %s
|
||||||
; PR4684
|
; PR4684
|
||||||
|
|
||||||
target datalayout =
|
target datalayout =
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -mtriple=i386-apple-darwin9 -O0 -regalloc=basic | FileCheck %s
|
; RUN: llc < %s -mtriple=i386-apple-darwin9 -O0 -optimize-regalloc -regalloc=basic | FileCheck %s
|
||||||
; rdar://6992609
|
; rdar://6992609
|
||||||
|
|
||||||
; CHECK: movl [[EDX:%e..]], 4(%esp)
|
; CHECK: movl [[EDX:%e..]], 4(%esp)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc -O0 -regalloc=basic < %s -march=x86-64 | FileCheck %s -check-prefix=X64
|
; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s -check-prefix=X64
|
||||||
|
|
||||||
; ModuleID = 'ts.c'
|
; ModuleID = 'ts.c'
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
|
@ -257,11 +257,6 @@ DisableSwitchTables(cl::Hidden, "disable-jump-tables",
|
|||||||
cl::desc("Do not generate jump tables."),
|
cl::desc("Do not generate jump tables."),
|
||||||
cl::init(false));
|
cl::init(false));
|
||||||
|
|
||||||
static cl::opt<bool>
|
|
||||||
EnableStrongPHIElim(cl::Hidden, "strong-phi-elim",
|
|
||||||
cl::desc("Use strong PHI elimination."),
|
|
||||||
cl::init(false));
|
|
||||||
|
|
||||||
static cl::opt<std::string>
|
static cl::opt<std::string>
|
||||||
TrapFuncName("trap-func", cl::Hidden,
|
TrapFuncName("trap-func", cl::Hidden,
|
||||||
cl::desc("Emit a call to trap function rather than a trap instruction"),
|
cl::desc("Emit a call to trap function rather than a trap instruction"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user