aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/CodeGen')
-rw-r--r--include/llvm/CodeGen/Analysis.h3
-rw-r--r--include/llvm/CodeGen/FastISel.h10
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h3
-rw-r--r--include/llvm/CodeGen/JITCodeEmitter.h3
-rw-r--r--include/llvm/CodeGen/LexicalScopes.h8
-rw-r--r--include/llvm/CodeGen/LiveInterval.h68
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h47
-rw-r--r--include/llvm/CodeGen/MachineDominators.h68
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h19
-rw-r--r--include/llvm/CodeGen/MachineFunction.h14
-rw-r--r--include/llvm/CodeGen/MachineFunctionAnalysis.h2
-rw-r--r--include/llvm/CodeGen/MachineInstr.h6
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h1
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h21
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h39
-rw-r--r--include/llvm/CodeGen/MachineTraceMetrics.h350
-rw-r--r--include/llvm/CodeGen/Passes.h10
-rw-r--r--include/llvm/CodeGen/RuntimeLibcalls.h5
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h24
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h55
-rw-r--r--include/llvm/CodeGen/ScheduleDFS.h72
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h20
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h35
-rw-r--r--include/llvm/CodeGen/ValueTypes.h2
24 files changed, 689 insertions, 196 deletions
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h
index 81e75d894d..ce9ca0a058 100644
--- a/include/llvm/CodeGen/Analysis.h
+++ b/include/llvm/CodeGen/Analysis.h
@@ -86,8 +86,7 @@ ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred);
/// between it and the return.
///
/// This function only tests target-independent requirements.
-bool isInTailCallPosition(ImmutableCallSite CS, Attribute CalleeRetAttr,
- const TargetLowering &TLI);
+bool isInTailCallPosition(ImmutableCallSite CS, const TargetLowering &TLI);
} // End llvm namespace
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 05619050a3..705db7e643 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -90,6 +90,11 @@ public:
/// getCurDebugLoc() - Return current debug location information.
DebugLoc getCurDebugLoc() const { return DL; }
+
+ /// LowerArguments - Do "fast" instruction selection for function arguments
+ /// and append machine instructions to the current block. Return true if
+ /// it is successful.
+ bool LowerArguments();
/// SelectInstruction - Do "fast" instruction selection for the given
/// LLVM IR instruction, and append generated machine instructions to
@@ -160,6 +165,11 @@ protected:
///
virtual bool
TargetSelectInstruction(const Instruction *I) = 0;
+
+ /// FastLowerArguments - This method is called by target-independent code to
+ /// do target specific argument lowering. It returns true if it was
+ /// successful.
+ virtual bool FastLowerArguments();
/// FastEmit_r - This method is called by target-independent code
/// to request that an instruction with the given type and opcode
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 47170e4e58..e9c98303e3 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -455,6 +455,9 @@ namespace ISD {
FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
FLOG, FLOG2, FLOG10, FEXP, FEXP2,
FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR,
+
+ /// FSINCOS - Compute both fsin and fcos as a single operation.
+ FSINCOS,
/// LOAD and STORE have token chains as their first operand, then the same
/// operands as an LLVM load/store instruction, then an offset node that
diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h
index e14d04e422..bc12b93d75 100644
--- a/include/llvm/CodeGen/JITCodeEmitter.h
+++ b/include/llvm/CodeGen/JITCodeEmitter.h
@@ -207,8 +207,7 @@ public:
/// emitString - This callback is invoked when a String needs to be
/// written to the output stream.
void emitString(const std::string &String) {
- for (unsigned i = 0, N = static_cast<unsigned>(String.size());
- i < N; ++i) {
+ for (size_t i = 0, N = String.size(); i < N; ++i) {
uint8_t C = String[i];
emitByte(C);
}
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
index 04710bc448..5eeb5b8b08 100644
--- a/include/llvm/CodeGen/LexicalScopes.h
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -159,9 +159,6 @@ public:
LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0) {
-#ifndef NDEBUG
- IndentLevel = 0;
-#endif
// @LOCALMOD-BEGIN -- Hack for bug
// http://code.google.com/p/nativeclient/issues/detail?id=2786
#ifndef NDEBUG
@@ -236,7 +233,7 @@ public:
void setDFSIn(unsigned I) { DFSIn = I; }
/// dump - print lexical scope.
- void dump() const;
+ void dump(unsigned Indent = 0) const;
private:
LexicalScope *Parent; // Parent to this scope.
@@ -252,9 +249,6 @@ private:
const MachineInstr *FirstInsn; // First instruction of this scope.
unsigned DFSIn, DFSOut; // In & Out Depth use to determine
// scope nesting.
-#ifndef NDEBUG
- mutable unsigned IndentLevel; // Private state for dump()
-#endif
};
} // end llvm namespace
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 95760758de..244be9c501 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -86,9 +86,10 @@ namespace llvm {
SlotIndex end; // End point of the interval (exclusive)
VNInfo *valno; // identifier for the value contained in this interval.
+ LiveRange() : valno(0) {}
+
LiveRange(SlotIndex S, SlotIndex E, VNInfo *V)
: start(S), end(E), valno(V) {
-
assert(S < E && "Cannot create empty or backwards range");
}
@@ -373,8 +374,8 @@ namespace llvm {
/// addRange - Add the specified LiveRange to this interval, merging
/// intervals as appropriate. This returns an iterator to the inserted live
/// range (which may have grown since it was inserted.
- void addRange(LiveRange LR) {
- addRangeFrom(LR, ranges.begin());
+ iterator addRange(LiveRange LR) {
+ return addRangeFrom(LR, ranges.begin());
}
/// extendInBlock - If this interval is live before Kill in the basic block
@@ -460,9 +461,6 @@ namespace llvm {
void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd);
Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr);
void markValNoForDeletion(VNInfo *V);
- void mergeIntervalRanges(const LiveInterval &RHS,
- VNInfo *LHSValNo = 0,
- const VNInfo *RHSValNo = 0);
LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION;
@@ -473,6 +471,64 @@ namespace llvm {
return OS;
}
+ /// Helper class for performant LiveInterval bulk updates.
+ ///
+ /// Calling LiveInterval::addRange() repeatedly can be expensive on large
+ /// live ranges because segments after the insertion point may need to be
+ /// shifted. The LiveRangeUpdater class can defer the shifting when adding
+ /// many segments in order.
+ ///
+ /// The LiveInterval will be in an invalid state until flush() is called.
+ class LiveRangeUpdater {
+ LiveInterval *LI;
+ SlotIndex LastStart;
+ LiveInterval::iterator WriteI;
+ LiveInterval::iterator ReadI;
+ SmallVector<LiveRange, 16> Spills;
+ void mergeSpills();
+
+ public:
+ /// Create a LiveRangeUpdater for adding segments to LI.
+ /// LI will temporarily be in an invalid state until flush() is called.
+ LiveRangeUpdater(LiveInterval *li = 0) : LI(li) {}
+
+ ~LiveRangeUpdater() { flush(); }
+
+ /// Add a segment to LI and coalesce when possible, just like LI.addRange().
+ /// Segments should be added in increasing start order for best performance.
+ void add(LiveRange);
+
+ void add(SlotIndex Start, SlotIndex End, VNInfo *VNI) {
+ add(LiveRange(Start, End, VNI));
+ }
+
+ /// Return true if the LI is currently in an invalid state, and flush()
+ /// needs to be called.
+ bool isDirty() const { return LastStart.isValid(); }
+
+ /// Flush the updater state to LI so it is valid and contains all added
+ /// segments.
+ void flush();
+
+ /// Select a different destination live range.
+ void setDest(LiveInterval *li) {
+ if (LI != li && isDirty())
+ flush();
+ LI = li;
+ }
+
+ /// Get the current destination live range.
+ LiveInterval *getDest() const { return LI; }
+
+ void dump() const;
+ void print(raw_ostream&) const;
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const LiveRangeUpdater &X) {
+ X.print(OS);
+ return OS;
+ }
+
/// LiveRangeQuery - Query information about a live range around a given
/// instruction. This class hides the implementation details of live ranges,
/// and it should be used as the primary interface for examining live ranges
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index 9e89519b28..4632368157 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -53,7 +53,6 @@ namespace llvm {
const TargetRegisterInfo* TRI;
const TargetInstrInfo* TII;
AliasAnalysis *AA;
- LiveVariables* LV;
SlotIndexes* Indexes;
MachineDominatorTree *DomTree;
LiveRangeCalc *LRCalc;
@@ -215,6 +214,13 @@ namespace llvm {
return Indexes->getMBBFromIndex(index);
}
+ void insertMBBInMaps(MachineBasicBlock *MBB) {
+ Indexes->insertMBBInMaps(MBB);
+ assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
+ "Blocks must be added in order.");
+ RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
+ }
+
SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) {
return Indexes->insertMachineInstrInMaps(MI);
}
@@ -275,6 +281,21 @@ namespace llvm {
void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart,
bool UpdateFlags = false);
+ /// repairIntervalsInRange - Update live intervals for instructions in a
+ /// range of iterators. It is intended for use after target hooks that may
+ /// insert or remove instructions, and is only efficient for a small number
+ /// of instructions.
+ ///
+ /// OrigRegs is a vector of registers that were originally used by the
+ /// instructions in the range between the two iterators.
+ ///
+ /// Currently, the only only changes that are supported are simple removal
+ /// and addition of uses.
+ void repairIntervalsInRange(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator Begin,
+ MachineBasicBlock::iterator End,
+ ArrayRef<unsigned> OrigRegs);
+
// Register mask functions.
//
// Machine instructions may use a register mask operand to indicate that a
@@ -352,36 +373,12 @@ namespace llvm {
}
private:
- /// computeIntervals - Compute live intervals.
- void computeIntervals();
-
/// Compute live intervals for all virtual registers.
void computeVirtRegs();
/// Compute RegMaskSlots and RegMaskBits.
void computeRegMasks();
- /// handleRegisterDef - update intervals for a register def
- /// (calls handleVirtualRegisterDef)
- void handleRegisterDef(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator MI,
- SlotIndex MIIdx,
- MachineOperand& MO, unsigned MOIdx);
-
- /// isPartialRedef - Return true if the specified def at the specific index
- /// is partially re-defining the specified live interval. A common case of
- /// this is a definition of the sub-register.
- bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
- LiveInterval &interval);
-
- /// handleVirtualRegisterDef - update intervals for a virtual
- /// register def
- void handleVirtualRegisterDef(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator MI,
- SlotIndex MIIdx, MachineOperand& MO,
- unsigned MOIdx,
- LiveInterval& interval);
-
static LiveInterval* createInterval(unsigned Reg);
void printInstrs(raw_ostream &O) const;
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
index 40b2542fd6..e41d206da6 100644
--- a/include/llvm/CodeGen/MachineDominators.h
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -41,15 +41,15 @@ class MachineDominatorTree : public MachineFunctionPass {
public:
static char ID; // Pass ID, replacement for typeid
DominatorTreeBase<MachineBasicBlock>* DT;
-
+
MachineDominatorTree();
-
+
~MachineDominatorTree();
-
+
DominatorTreeBase<MachineBasicBlock>& getBase() { return *DT; }
-
+
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
-
+
/// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
@@ -57,33 +57,35 @@ public:
inline const std::vector<MachineBasicBlock*> &getRoots() const {
return DT->getRoots();
}
-
+
inline MachineBasicBlock *getRoot() const {
return DT->getRoot();
}
-
+
inline MachineDomTreeNode *getRootNode() const {
return DT->getRootNode();
}
-
+
virtual bool runOnMachineFunction(MachineFunction &F);
-
- inline bool dominates(MachineDomTreeNode* A, MachineDomTreeNode* B) const {
+
+ inline bool dominates(const MachineDomTreeNode* A,
+ const MachineDomTreeNode* B) const {
return DT->dominates(A, B);
}
-
- inline bool dominates(MachineBasicBlock* A, MachineBasicBlock* B) const {
+
+ inline bool dominates(const MachineBasicBlock* A,
+ const MachineBasicBlock* B) const {
return DT->dominates(A, B);
}
-
+
// dominates - Return true if A dominates B. This performs the
// special checks necessary if A and B are in the same basic block.
- bool dominates(MachineInstr *A, MachineInstr *B) const {
- MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
+ bool dominates(const MachineInstr *A, const MachineInstr *B) const {
+ const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
if (BBA != BBB) return DT->dominates(BBA, BBB);
// Loop through the basic block until we find A or B.
- MachineBasicBlock::iterator I = BBA->begin();
+ MachineBasicBlock::const_iterator I = BBA->begin();
for (; &*I != A && &*I != B; ++I)
/*empty*/ ;
@@ -95,43 +97,43 @@ public:
// return &*I == B;
//}
}
-
+
inline bool properlyDominates(const MachineDomTreeNode* A,
- MachineDomTreeNode* B) const {
+ const MachineDomTreeNode* B) const {
return DT->properlyDominates(A, B);
}
-
- inline bool properlyDominates(MachineBasicBlock* A,
- MachineBasicBlock* B) const {
+
+ inline bool properlyDominates(const MachineBasicBlock* A,
+ const MachineBasicBlock* B) const {
return DT->properlyDominates(A, B);
}
-
+
/// findNearestCommonDominator - Find nearest common dominator basic block
/// for basic block A and B. If there is no such block then return NULL.
inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
MachineBasicBlock *B) {
return DT->findNearestCommonDominator(A, B);
}
-
+
inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
return DT->getNode(BB);
}
-
+
/// getNode - return the (Post)DominatorTree node for the specified basic
/// block. This is the same as using operator[] on this class.
///
inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
return DT->getNode(BB);
}
-
+
/// addNewBlock - Add a new node to the dominator tree information. This
- /// creates a new node as a child of DomBB dominator node,linking it into
+ /// creates a new node as a child of DomBB dominator node,linking it into
/// the children list of the immediate dominator.
inline MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB,
MachineBasicBlock *DomBB) {
return DT->addNewBlock(BB, DomBB);
}
-
+
/// changeImmediateDominator - This method is used to update the dominator
/// tree information when a node's immediate dominator changes.
///
@@ -139,19 +141,19 @@ public:
MachineBasicBlock* NewIDom) {
DT->changeImmediateDominator(N, NewIDom);
}
-
+
inline void changeImmediateDominator(MachineDomTreeNode *N,
MachineDomTreeNode* NewIDom) {
DT->changeImmediateDominator(N, NewIDom);
}
-
+
/// eraseNode - Removes a node from the dominator tree. Block must not
/// dominate any other blocks. Removes node from its immediate dominator's
/// children list. Deletes dominator node associated with basic block BB.
inline void eraseNode(MachineBasicBlock *BB) {
DT->eraseNode(BB);
}
-
+
/// splitBlock - BB is split and now it has one successor. Update dominator
/// tree to reflect this change.
inline void splitBlock(MachineBasicBlock* NewBB) {
@@ -160,12 +162,12 @@ public:
/// isReachableFromEntry - Return true if A is dominated by the entry
/// block of the function containing it.
- bool isReachableFromEntry(MachineBasicBlock *A) {
+ bool isReachableFromEntry(const MachineBasicBlock *A) {
return DT->isReachableFromEntry(A);
}
virtual void releaseMemory();
-
+
virtual void print(raw_ostream &OS, const Module*) const;
};
@@ -179,7 +181,7 @@ template<class T> struct GraphTraits;
template <> struct GraphTraits<MachineDomTreeNode *> {
typedef MachineDomTreeNode NodeType;
typedef NodeType::iterator ChildIteratorType;
-
+
static NodeType *getEntryNode(NodeType *N) {
return N;
}
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 0748b9ab24..93d77287d7 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -493,23 +493,11 @@ public:
return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
}
- /// CreateStackObjectWithMinAlign - Create a new statically sized stack
- /// object, returning a nonnegative identifier to represent it. This function
- /// takes a preferred alignment and a minimal alignment.
- ///
- int CreateStackObjectWithMinAlign(uint64_t Size, unsigned PrefAlignment,
- unsigned MinAlignment, bool isSS,
- bool MayNeedSP = false, const AllocaInst *Alloca = 0);
-
/// CreateStackObject - Create a new statically sized stack object, returning
- /// a nonnegative identifier to represent it. Will not emit an error when
- /// Alignment can't be satisfied.
+ /// a nonnegative identifier to represent it.
///
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
- bool MayNeedSP = false, const AllocaInst *Alloca = 0) {
- return CreateStackObjectWithMinAlign(Size, Alignment, 0, isSS,
- MayNeedSP, Alloca);
- }
+ bool MayNeedSP = false, const AllocaInst *Alloca = 0);
/// CreateSpillStackObject - Create a new statically sized stack object that
/// represents a spill slot, returning a nonnegative identifier to represent
@@ -529,8 +517,7 @@ public:
/// variable sized object is created, whether or not the index returned is
/// actually used.
///
- int CreateVariableSizedObject(unsigned PrefAlignment, unsigned MinAlignment,
- const AllocaInst *Alloca = 0);
+ int CreateVariableSizedObject(unsigned Alignment);
/// getCalleeSavedInfo - Returns a reference to call saved info vector for the
/// current function.
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index cd704c1c53..82c4cd6598 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -131,6 +131,9 @@ class MachineFunction {
/// about the control flow of such functions.
bool ExposesReturnsTwice;
+ /// True if the function includes MS-style inline assembly.
+ bool HasMSInlineAsm;
+
MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION;
void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION;
public:
@@ -214,6 +217,17 @@ public:
void setExposesReturnsTwice(bool B) {
ExposesReturnsTwice = B;
}
+
+ /// Returns true if the function contains any MS-style inline assembly.
+ bool hasMSInlineAsm() const {
+ return HasMSInlineAsm;
+ }
+
+ /// Set a flag that indicates that the function contains MS-style inline
+ /// assembly.
+ void setHasMSInlineAsm(bool B) {
+ HasMSInlineAsm = B;
+ }
/// getInfo - Keep track of various per-function pieces of information for
/// backends that would like to do so.
diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h
index 33b81434ce..112f07ea50 100644
--- a/include/llvm/CodeGen/MachineFunctionAnalysis.h
+++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h
@@ -15,11 +15,11 @@
#define LLVM_CODEGEN_MACHINEFUNCTIONANALYSIS_H
#include "llvm/Pass.h"
-#include "llvm/Target/TargetMachine.h"
namespace llvm {
class MachineFunction;
+class TargetMachine;
/// MachineFunctionAnalysis - This class is a Pass that manages a
/// MachineFunction object.
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 17eeb94e3f..195cce7a64 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -642,6 +642,9 @@ public:
bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
+ bool isMSInlineAsm() const {
+ return getOpcode() == TargetOpcode::INLINEASM && getInlineAsmDialect();
+ }
bool isStackAligningInlineAsm() const;
InlineAsm::AsmDialect getInlineAsmDialect() const;
bool isInsertSubreg() const {
@@ -948,7 +951,8 @@ public:
//
// Debugging support
//
- void print(raw_ostream &OS, const TargetMachine *TM = 0) const;
+ void print(raw_ostream &OS, const TargetMachine *TM = 0,
+ bool SkipOpers = false) const;
void dump() const;
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index 6194d05238..1db6252ef4 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -35,7 +35,6 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Metadata.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MachineLocation.h"
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 36427e90ca..875285b470 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -99,13 +99,11 @@ class MachineRegisterInfo {
/// started.
BitVector ReservedRegs;
- /// LiveIns/LiveOuts - Keep track of the physical registers that are
- /// livein/liveout of the function. Live in values are typically arguments in
- /// registers, live out values are typically return values in registers.
- /// LiveIn values are allowed to have virtual registers associated with them,
- /// stored in the second element.
+ /// Keep track of the physical registers that are live in to the function.
+ /// Live in values are typically arguments in registers, live out values are
+ /// typically return values in registers. LiveIn values are allowed to have
+ /// virtual registers associated with them, stored in the second element.
std::vector<std::pair<unsigned, unsigned> > LiveIns;
- std::vector<unsigned> LiveOuts;
MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
@@ -379,6 +377,12 @@ public:
return false;
}
+ /// Mark the specified register unit as used in this function.
+ /// This should only be called during and after register allocation.
+ void setRegUnitUsed(unsigned RegUnit) {
+ UsedRegUnits.set(RegUnit);
+ }
+
/// setPhysRegUsed - Mark the specified register used in this function.
/// This should only be called during and after register allocation.
void setPhysRegUsed(unsigned Reg) {
@@ -468,7 +472,6 @@ public:
void addLiveIn(unsigned Reg, unsigned vreg = 0) {
LiveIns.push_back(std::make_pair(Reg, vreg));
}
- void addLiveOut(unsigned Reg) { LiveOuts.push_back(Reg); }
// Iteration support for live in/out sets. These sets are kept in sorted
// order by their register number.
@@ -478,12 +481,8 @@ public:
livein_iterator livein_begin() const { return LiveIns.begin(); }
livein_iterator livein_end() const { return LiveIns.end(); }
bool livein_empty() const { return LiveIns.empty(); }
- liveout_iterator liveout_begin() const { return LiveOuts.begin(); }
- liveout_iterator liveout_end() const { return LiveOuts.end(); }
- bool liveout_empty() const { return LiveOuts.empty(); }
bool isLiveIn(unsigned Reg) const;
- bool isLiveOut(unsigned Reg) const;
/// getLiveInPhysReg - If VReg is a live-in virtual register, return the
/// corresponding live-in physical register.
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index 68489884dc..57febe7746 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -43,6 +43,7 @@ class MachineDominatorTree;
class MachineLoopInfo;
class RegisterClassInfo;
class ScheduleDAGInstrs;
+class SchedDFSResult;
/// MachineSchedContext provides enough context from the MachineScheduler pass
/// for the target to instantiate a scheduler.
@@ -119,6 +120,9 @@ public:
/// be scheduled at the bottom.
virtual SUnit *pickNode(bool &IsTopNode) = 0;
+ /// \brief Scheduler callback to notify that a new subtree is scheduled.
+ virtual void scheduleTree(unsigned SubtreeID) {}
+
/// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an
/// instruction and updated scheduled/remaining flags in the DAG nodes.
virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
@@ -164,6 +168,8 @@ public:
iterator end() { return Queue.end(); }
+ ArrayRef<SUnit*> elements() { return Queue; }
+
iterator find(SUnit *SU) {
return std::find(Queue.begin(), Queue.end(), SU);
}
@@ -202,6 +208,11 @@ protected:
RegisterClassInfo *RegClassInfo;
MachineSchedStrategy *SchedImpl;
+ /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
+ /// will be empty.
+ SchedDFSResult *DFSResult;
+ BitVector ScheduledTrees;
+
/// Topo - A topological ordering for SUnits which permits fast IsReachable
/// and similar queries.
ScheduleDAGTopologicalSort Topo;
@@ -243,7 +254,7 @@ protected:
public:
ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
- AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
+ AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), DFSResult(0),
Topo(SUnits, &ExitSU), RPTracker(RegPressure), CurrentTop(),
TopRPTracker(TopPressure), CurrentBottom(), BotRPTracker(BotPressure),
NextClusterPred(NULL), NextClusterSucc(NULL) {
@@ -252,10 +263,7 @@ public:
#endif
}
- virtual ~ScheduleDAGMI() {
- DeleteContainerPointers(Mutations);
- delete SchedImpl;
- }
+ virtual ~ScheduleDAGMI();
/// Add a postprocessing step to the DAG builder.
/// Mutations are applied in the order that they are added after normal DAG
@@ -308,6 +316,18 @@ public:
const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
+ /// Compute a DFSResult after DAG building is complete, and before any
+ /// queue comparisons.
+ void computeDFSResult();
+
+ /// Return a non-null DFS result if the scheduling strategy initialized it.
+ const SchedDFSResult *getDFSResult() const { return DFSResult; }
+
+ BitVector &getScheduledTrees() { return ScheduledTrees; }
+
+ void viewGraph(const Twine &Name, const Twine &Title) LLVM_OVERRIDE;
+ void viewGraph() LLVM_OVERRIDE;
+
protected:
// Top-Level entry points for the schedule() driver...
@@ -321,8 +341,8 @@ protected:
/// instances of ScheduleDAGMI to perform custom DAG postprocessing.
void postprocessDAG();
- /// Identify DAG roots and setup scheduler queues.
- void initQueues();
+ /// Release ExitSU predecessors and setup scheduler queues.
+ void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
/// Move an instruction and update register pressure.
void scheduleMI(SUnit *SU, bool IsTopNode);
@@ -340,12 +360,13 @@ protected:
void initRegPressure();
- void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
+ void updateScheduledPressure(const std::vector<unsigned> &NewMaxPressure);
void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
bool checkSchedLimit();
- void releaseRoots();
+ void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
+ SmallVectorImpl<SUnit*> &BotRoots);
void releaseSucc(SUni