namespace llvm {
- class FunctionPass;
- class MachineFunctionPass;
- class PassInfo;
- class PassManagerBase;
- class TargetLoweringBase;
- class TargetLowering;
- class TargetRegisterClass;
- class raw_ostream;
+class FunctionPass;
+class MachineFunctionPass;
+class PassConfigImpl;
+class PassInfo;
+class ScheduleDAGInstrs;
+class TargetLowering;
+class TargetLoweringBase;
+class TargetRegisterClass;
+class raw_ostream;
+struct MachineSchedContext;
+
+// The old pass manager infrastructure is hidden in a legacy namespace now.
+namespace legacy {
+class PassManagerBase;
}
+using legacy::PassManagerBase;
-namespace llvm {
+/// Discriminated union of Pass ID types.
+///
+/// The PassConfig API prefers dealing with IDs because they are safer and more
+/// efficient. IDs decouple configuration from instantiation. This way, when a
+/// pass is overriden, it isn't unnecessarily instantiated. It is also unsafe to
+/// refer to a Pass pointer after adding it to a pass manager, which deletes
+/// redundant pass instances.
+///
+/// However, it is convient to directly instantiate target passes with
+/// non-default ctors. These often don't have a registered PassInfo. Rather than
+/// force all target passes to implement the pass registry boilerplate, allow
+/// the PassConfig API to handle either type.
+///
+/// AnalysisID is sadly char*, so PointerIntPair won't work.
+class IdentifyingPassPtr {
+ union {
+ AnalysisID ID;
+ Pass *P;
+ };
+ bool IsInstance;
+public:
+ IdentifyingPassPtr() : P(nullptr), IsInstance(false) {}
+ IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr), IsInstance(false) {}
+ IdentifyingPassPtr(Pass *InstancePtr) : P(InstancePtr), IsInstance(true) {}
-class PassConfigImpl;
+ bool isValid() const { return P; }
+ bool isInstance() const { return IsInstance; }
+
+ AnalysisID getID() const {
+ assert(!IsInstance && "Not a Pass ID");
+ return ID;
+ }
+ Pass *getInstance() const {
+ assert(IsInstance && "Not a Pass Instance");
+ return P;
+ }
+};
+
+template <> struct isPodLike<IdentifyingPassPtr> {
+ static const bool value = true;
+};
/// Target-Independent Code Generator Pass Configuration Options.
///
return *static_cast<TMC*>(TM);
}
- const TargetLowering *getTargetLowering() const {
- return TM->getTargetLowering();
- }
-
//
void setInitialized() { Initialized = true; }
void setStartStopPasses(AnalysisID Start, AnalysisID Stop) {
StartAfter = Start;
StopAfter = Stop;
- Started = (StartAfter == 0);
+ Started = (StartAfter == nullptr);
}
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
/// Allow the target to override a specific pass without overriding the pass
/// pipeline. When passes are added to the standard pipeline at the
/// point where StandardID is expected, add TargetID in its place.
- void substitutePass(AnalysisID StandardID, AnalysisID TargetID);
+ void substitutePass(AnalysisID StandardID, IdentifyingPassPtr TargetID);
/// Insert InsertedPassID pass after TargetPassID pass.
- void insertPass(AnalysisID TargetPassID, AnalysisID InsertedPassID);
+ void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID);
/// Allow the target to enable a specific standard pass by default.
void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); }
/// Allow the target to disable a specific standard pass by default.
- void disablePass(AnalysisID PassID) { substitutePass(PassID, 0); }
+ void disablePass(AnalysisID PassID) {
+ substitutePass(PassID, IdentifyingPassPtr());
+ }
/// Return the pass substituted for StandardID by the target.
/// If no substitution exists, return StandardID.
- AnalysisID getPassSubstitution(AnalysisID StandardID) const;
+ IdentifyingPassPtr getPassSubstitution(AnalysisID StandardID) const;
/// Return true if the optimized regalloc pipeline is enabled.
bool getOptimizeRegAlloc() const;
/// Fully developed targets will not generally override this.
virtual void addMachinePasses();
+ /// Create an instance of ScheduleDAGInstrs to be run within the standard
+ /// MachineScheduler pass for this function and target at the current
+ /// optimization level.
+ ///
+ /// This can also be used to plug a new MachineSchedStrategy into an instance
+ /// of the standard ScheduleDAGMI:
+ /// return new ScheduleDAGMI(C, new MyStrategy(C))
+ ///
+ /// Return NULL to select the default (generic) machine scheduler.
+ virtual ScheduleDAGInstrs *
+ createMachineScheduler(MachineSchedContext *C) const {
+ return nullptr;
+ }
+
+ /// Similar to createMachineScheduler but used when postRA machine scheduling
+ /// is enabled.
+ virtual ScheduleDAGInstrs *
+ createPostMachineScheduler(MachineSchedContext *C) const {
+ return nullptr;
+ }
+
protected:
// Helper to verify the analysis is really immutable.
void setOpt(bool &Opt, bool Val);
return false;
}
- /// addFinalizeRegAlloc - This method may be implemented by targets that want
- /// to run passes within the regalloc pipeline, immediately after the register
- /// allocation pass itself. These passes run as soon as virtual regisiters
- /// have been rewritten to physical registers but before and other postRA
- /// optimization happens. Targets that have marked instructions for bundling
- /// must have finalized those bundles by the time these passes have run,
- /// because subsequent passes are not guaranteed to be bundle-aware.
- virtual bool addFinalizeRegAlloc() {
- return false;
- }
-
/// addPostRegAlloc - This method may be implemented by targets that want to
/// run passes after register allocation pass pipeline but before
/// prolog-epilog insertion. This should return true if -print-machineinstrs
AnalysisID addPass(AnalysisID PassID);
/// Add a pass to the PassManager if that pass is supposed to be run, as
- /// determined by the StartAfter and StopAfter options.
+ /// determined by the StartAfter and StopAfter options. Takes ownership of the
+ /// pass.
void addPass(Pass *P);
/// addMachinePasses helper to create the target-selected or overriden
/// List of target independent CodeGen pass IDs.
namespace llvm {
+ FunctionPass *createAtomicExpandLoadLinkedPass(const TargetMachine *TM);
+
/// \brief Create a basic TargetTransformInfo analysis pass.
///
/// This pass implements the target transform info analysis using the target
/// independent information available to the LLVM code generator.
ImmutablePass *
- createBasicTargetTransformInfoPass(const TargetLoweringBase *TLI);
+ createBasicTargetTransformInfoPass(const TargetMachine *TM);
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
/// work well with unreachable basic blocks (what live ranges make sense for a
createMachineFunctionPrinterPass(raw_ostream &OS,
const std::string &Banner ="");
+ /// createCodeGenPreparePass - Transform the code to expose more pattern
+ /// matching during instruction selection.
+ FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr);
+
+ /// AtomicExpandLoadLinkedID -- FIXME
+ extern char &AtomicExpandLoadLinkedID;
+
/// MachineLoopInfo - This pass is a loop analysis pass.
extern char &MachineLoopInfoID;
/// MachineDominators - This pass is a machine dominators analysis pass.
extern char &MachineDominatorsID;
+/// MachineDominanaceFrontier - This pass is a machine dominators analysis pass.
+ extern char &MachineDominanceFrontierID;
+
/// EdgeBundles analysis - Bundle machine CFG edges.
extern char &EdgeBundlesID;
/// these register allocator like this: AU.addRequiredID(PHIEliminationID);
extern char &PHIEliminationID;
- /// StrongPHIElimination - This pass eliminates machine instruction PHI
- /// nodes by inserting copy instructions. This destroys SSA information, but
- /// is the desired input for some register allocators. This pass is
- /// "required" by these register allocator like this:
- /// AU.addRequiredID(PHIEliminationID);
- /// This pass is still in development
- extern char &StrongPHIEliminationID;
-
/// LiveIntervals - This analysis keeps track of the live ranges of virtual
/// and physical registers.
extern char &LiveIntervalsID;
/// MachineScheduler - This pass schedules machine instructions.
extern char &MachineSchedulerID;
+ /// PostMachineScheduler - This pass schedules machine instructions postRA.
+ extern char &PostMachineSchedulerID;
+
/// SpillPlacement analysis. Suggest optimal placement of spill code between
/// basic blocks.
extern char &SpillPlacementID;
/// inserting cmov instructions.
extern char &EarlyIfConverterID;
+ /// This pass performs instruction combining using trace metrics to estimate
+ /// critical-path and resource depth.
+ extern char &MachineCombinerID;
+
/// StackSlotColoring - This pass performs stack coloring and merging.
/// It merges disjoint allocas to reduce the stack size.
extern char &StackColoringID;
/// information.
extern char &MachineBlockPlacementStatsID;
- /// Code Placement - This pass optimize code placement and aligns loop
- /// headers to target specific alignment boundary.
- extern char &CodePlacementOptID;
-
/// GCLowering Pass - Performs target-independent LLVM IR transformations for
/// highly portable strategies.
///
/// createStackProtectorPass - This pass adds stack protectors to functions.
///
- FunctionPass *createStackProtectorPass(const TargetLoweringBase *tli);
+ FunctionPass *createStackProtectorPass(const TargetMachine *TM);
/// createMachineVerifierPass - This pass verifies cenerated machine code
/// instructions for correctness.
///
- FunctionPass *createMachineVerifierPass(const char *Banner = 0);
+ FunctionPass *createMachineVerifierPass(const char *Banner = nullptr);
/// createDwarfEHPass - This pass mulches exception handling code into a form
/// adapted to code generation. Required if using dwarf exception handling.
- FunctionPass *createDwarfEHPass(const TargetMachine *tm);
+ FunctionPass *createDwarfEHPass(const TargetMachine *TM);
/// createSjLjEHPreparePass - This pass adapts exception handling code to use
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
///
- FunctionPass *createSjLjEHPreparePass(const TargetLoweringBase *tli);
+ FunctionPass *createSjLjEHPreparePass(const TargetMachine *TM);
/// LocalStackSlotAllocation - This pass assigns local frame indices to stack
/// slots relative to one another and allocates base registers to access them
/// bundles (created earlier, e.g. during pre-RA scheduling).
extern char &FinalizeMachineBundlesID;
+ /// StackMapLiveness - This pass analyses the register live-out set of
+ /// stackmap/patchpoint intrinsics and attaches the calculated information to
+ /// the intrinsic for later emission to the StackMap.
+ extern char &StackMapLivenessID;
+
+ /// createJumpInstrTables - This pass creates jump-instruction tables.
+ ModulePass *createJumpInstrTablesPass();
} // End llvm namespace
+/// This initializer registers TargetMachine constructor, so the pass being
+/// initialized can use target dependent interfaces. Please do not move this
+/// macro to be together with INITIALIZE_PASS, which is a complete target
+/// independent initializer, and we don't want to make libScalarOpts depend
+/// on libCodeGen.
+#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \
+ static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+ PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
+ PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis, \
+ PassInfo::TargetMachineCtor_t(callTargetMachineCtor< passName >)); \
+ Registry.registerPass(*PI, true); \
+ return PI; \
+ } \
+ void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+ CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+ }
+
#endif