mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-03 10:54:42 +00:00
whitespace
llvm-svn: 122539
This commit is contained in:
parent
a7ad357a13
commit
53f4556c64
@ -20,25 +20,25 @@
|
||||
|
||||
namespace llvm {
|
||||
class LatencyPriorityQueue;
|
||||
|
||||
|
||||
/// Sorting functions for the Available queue.
|
||||
struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> {
|
||||
LatencyPriorityQueue *PQ;
|
||||
explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {}
|
||||
|
||||
|
||||
bool operator()(const SUnit* left, const SUnit* right) const;
|
||||
};
|
||||
|
||||
class LatencyPriorityQueue : public SchedulingPriorityQueue {
|
||||
// SUnits - The SUnits for the current graph.
|
||||
std::vector<SUnit> *SUnits;
|
||||
|
||||
|
||||
/// NumNodesSolelyBlocking - This vector contains, for every node in the
|
||||
/// Queue, the number of nodes that the node is the sole unscheduled
|
||||
/// predecessor for. This is used as a tie-breaker heuristic for better
|
||||
/// mobility.
|
||||
std::vector<unsigned> NumNodesSolelyBlocking;
|
||||
|
||||
|
||||
/// Queue - The queue.
|
||||
std::vector<SUnit*> Queue;
|
||||
latency_sort Picker;
|
||||
@ -62,21 +62,21 @@ namespace llvm {
|
||||
void releaseState() {
|
||||
SUnits = 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned getLatency(unsigned NodeNum) const {
|
||||
assert(NodeNum < (*SUnits).size());
|
||||
return (*SUnits)[NodeNum].getHeight();
|
||||
}
|
||||
|
||||
|
||||
unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
|
||||
assert(NodeNum < NumNodesSolelyBlocking.size());
|
||||
return NumNodesSolelyBlocking[NodeNum];
|
||||
}
|
||||
|
||||
|
||||
bool empty() const { return Queue.empty(); }
|
||||
|
||||
|
||||
virtual void push(SUnit *U);
|
||||
|
||||
|
||||
virtual SUnit *pop();
|
||||
|
||||
virtual void remove(SUnit *SU);
|
||||
|
@ -232,8 +232,8 @@ namespace llvm {
|
||||
public:
|
||||
SUnit *OrigNode; // If not this, the node from which
|
||||
// this node was cloned.
|
||||
|
||||
// Preds/Succs - The SUnits before/after us in the graph.
|
||||
|
||||
// Preds/Succs - The SUnits before/after us in the graph.
|
||||
SmallVector<SDep, 4> Preds; // All sunit predecessors.
|
||||
SmallVector<SDep, 4> Succs; // All sunit successors.
|
||||
|
||||
@ -270,7 +270,7 @@ namespace llvm {
|
||||
public:
|
||||
const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
|
||||
const TargetRegisterClass *CopySrcRC;
|
||||
|
||||
|
||||
/// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
|
||||
/// an SDNode and any nodes flagged to it.
|
||||
SUnit(SDNode *node, unsigned nodenum)
|
||||
@ -353,7 +353,7 @@ namespace llvm {
|
||||
/// getDepth - Return the depth of this node, which is the length of the
|
||||
/// maximum path up to any node with has no predecessors.
|
||||
unsigned getDepth() const {
|
||||
if (!isDepthCurrent)
|
||||
if (!isDepthCurrent)
|
||||
const_cast<SUnit *>(this)->ComputeDepth();
|
||||
return Depth;
|
||||
}
|
||||
@ -361,7 +361,7 @@ namespace llvm {
|
||||
/// getHeight - Return the height of this node, which is the length of the
|
||||
/// maximum path down to any node with has no successors.
|
||||
unsigned getHeight() const {
|
||||
if (!isHeightCurrent)
|
||||
if (!isHeightCurrent)
|
||||
const_cast<SUnit *>(this)->ComputeHeight();
|
||||
return Height;
|
||||
}
|
||||
@ -393,7 +393,7 @@ namespace llvm {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// isSucc - Test if node N is a successor of this node.
|
||||
bool isSucc(SUnit *N) {
|
||||
for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
|
||||
@ -414,17 +414,17 @@ namespace llvm {
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// SchedulingPriorityQueue - This interface is used to plug different
|
||||
/// priorities computation algorithms into the list scheduler. It implements
|
||||
/// the interface of a standard priority queue, where nodes are inserted in
|
||||
/// the interface of a standard priority queue, where nodes are inserted in
|
||||
/// arbitrary order and returned in priority order. The computation of the
|
||||
/// priority and the representation of the queue are totally up to the
|
||||
/// implementation to decide.
|
||||
///
|
||||
///
|
||||
class SchedulingPriorityQueue {
|
||||
unsigned CurCycle;
|
||||
public:
|
||||
SchedulingPriorityQueue() : CurCycle(0) {}
|
||||
virtual ~SchedulingPriorityQueue() {}
|
||||
|
||||
|
||||
virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
|
||||
virtual void addNode(const SUnit *SU) = 0;
|
||||
virtual void updateNode(const SUnit *SU) = 0;
|
||||
@ -432,7 +432,7 @@ namespace llvm {
|
||||
|
||||
virtual bool empty() const = 0;
|
||||
virtual void push(SUnit *U) = 0;
|
||||
|
||||
|
||||
void push_all(const std::vector<SUnit *> &Nodes) {
|
||||
for (std::vector<SUnit *>::const_iterator I = Nodes.begin(),
|
||||
E = Nodes.end(); I != E; ++I)
|
||||
@ -457,7 +457,7 @@ namespace llvm {
|
||||
|
||||
unsigned getCurCycle() const {
|
||||
return CurCycle;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ScheduleDAG {
|
||||
@ -483,7 +483,7 @@ namespace llvm {
|
||||
/// using 'dot'.
|
||||
///
|
||||
void viewGraph();
|
||||
|
||||
|
||||
/// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock
|
||||
/// according to the order specified in Sequence.
|
||||
///
|
||||
@ -633,7 +633,7 @@ namespace llvm {
|
||||
/// Visited - a set of nodes visited during a DFS traversal.
|
||||
BitVector Visited;
|
||||
|
||||
/// DFS - make a DFS traversal and mark all nodes affected by the
|
||||
/// DFS - make a DFS traversal and mark all nodes affected by the
|
||||
/// edge insertion. These nodes will later get new topological indexes
|
||||
/// by means of the Shift method.
|
||||
void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);
|
||||
@ -648,7 +648,7 @@ namespace llvm {
|
||||
public:
|
||||
explicit ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits);
|
||||
|
||||
/// InitDAGTopologicalSorting - create the initial topological
|
||||
/// InitDAGTopologicalSorting - create the initial topological
|
||||
/// ordering from the DAG to be scheduled.
|
||||
void InitDAGTopologicalSorting();
|
||||
|
||||
|
@ -35,7 +35,7 @@ namespace llvm {
|
||||
class GCFunctionInfo;
|
||||
class ScheduleDAGSDNodes;
|
||||
class LoadInst;
|
||||
|
||||
|
||||
/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
|
||||
/// pattern-matching instruction selectors.
|
||||
class SelectionDAGISel : public MachineFunctionPass {
|
||||
@ -55,7 +55,7 @@ public:
|
||||
explicit SelectionDAGISel(const TargetMachine &tm,
|
||||
CodeGenOpt::Level OL = CodeGenOpt::Default);
|
||||
virtual ~SelectionDAGISel();
|
||||
|
||||
|
||||
const TargetLowering &getTargetLowering() { return TLI; }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
@ -63,18 +63,18 @@ public:
|
||||
virtual bool runOnMachineFunction(MachineFunction &MF);
|
||||
|
||||
virtual void EmitFunctionEntryCode() {}
|
||||
|
||||
|
||||
/// PreprocessISelDAG - This hook allows targets to hack on the graph before
|
||||
/// instruction selection starts.
|
||||
virtual void PreprocessISelDAG() {}
|
||||
|
||||
|
||||
/// PostprocessISelDAG() - This hook allows the target to hack on the graph
|
||||
/// right after selection.
|
||||
virtual void PostprocessISelDAG() {}
|
||||
|
||||
|
||||
/// Select - Main hook targets implement to select a node.
|
||||
virtual SDNode *Select(SDNode *N) = 0;
|
||||
|
||||
|
||||
/// SelectInlineAsmMemoryOperand - Select the specified address as a target
|
||||
/// addressing mode, according to the specified constraint code. If this does
|
||||
/// not match or is not implemented, return true. The resultant operands
|
||||
@ -101,13 +101,13 @@ public:
|
||||
/// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
|
||||
/// to use for this target when scheduling the DAG.
|
||||
virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer();
|
||||
|
||||
|
||||
|
||||
|
||||
// Opcodes used by the DAG state machine:
|
||||
enum BuiltinOpcodes {
|
||||
OPC_Scope,
|
||||
OPC_RecordNode,
|
||||
OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3,
|
||||
OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3,
|
||||
OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7,
|
||||
OPC_RecordMemRef,
|
||||
OPC_CaptureGlueInput,
|
||||
@ -129,7 +129,7 @@ public:
|
||||
OPC_CheckComplexPat,
|
||||
OPC_CheckAndImm, OPC_CheckOrImm,
|
||||
OPC_CheckFoldableChainNode,
|
||||
|
||||
|
||||
OPC_EmitInteger,
|
||||
OPC_EmitRegister,
|
||||
OPC_EmitConvertToTarget,
|
||||
@ -143,7 +143,7 @@ public:
|
||||
OPC_MarkGlueResults,
|
||||
OPC_CompleteMatch
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
OPFL_None = 0, // Node has no chain or glue input and isn't variadic.
|
||||
OPFL_Chain = 1, // Node has a chain input.
|
||||
@ -157,37 +157,37 @@ public:
|
||||
OPFL_Variadic4 = 5<<4, // Node is variadic, root has 4 fixed inputs.
|
||||
OPFL_Variadic5 = 6<<4, // Node is variadic, root has 5 fixed inputs.
|
||||
OPFL_Variadic6 = 7<<4, // Node is variadic, root has 6 fixed inputs.
|
||||
|
||||
|
||||
OPFL_VariadicInfo = OPFL_Variadic6
|
||||
};
|
||||
|
||||
|
||||
/// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the
|
||||
/// number of fixed arity values that should be skipped when copying from the
|
||||
/// root.
|
||||
static inline int getNumFixedFromVariadicInfo(unsigned Flags) {
|
||||
return ((Flags&OPFL_VariadicInfo) >> 4)-1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
/// DAGSize - Size of DAG being instruction selected.
|
||||
///
|
||||
unsigned DAGSize;
|
||||
|
||||
|
||||
/// ISelPosition - Node iterator marking the current position of
|
||||
/// instruction selection as it procedes through the topologically-sorted
|
||||
/// node list.
|
||||
SelectionDAG::allnodes_iterator ISelPosition;
|
||||
|
||||
|
||||
/// ISelUpdater - helper class to handle updates of the
|
||||
|
||||
/// ISelUpdater - helper class to handle updates of the
|
||||
/// instruction selection graph.
|
||||
class ISelUpdater : public SelectionDAG::DAGUpdateListener {
|
||||
SelectionDAG::allnodes_iterator &ISelPosition;
|
||||
public:
|
||||
explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
|
||||
: ISelPosition(isp) {}
|
||||
|
||||
|
||||
/// NodeDeleted - Handle nodes deleted from the graph. If the
|
||||
/// node being deleted is the current ISelPosition node, update
|
||||
/// ISelPosition.
|
||||
@ -196,46 +196,46 @@ protected:
|
||||
if (ISelPosition == SelectionDAG::allnodes_iterator(N))
|
||||
++ISelPosition;
|
||||
}
|
||||
|
||||
|
||||
/// NodeUpdated - Ignore updates for now.
|
||||
virtual void NodeUpdated(SDNode *N) {}
|
||||
};
|
||||
|
||||
|
||||
/// ReplaceUses - replace all uses of the old node F with the use
|
||||
/// of the new node T.
|
||||
void ReplaceUses(SDValue F, SDValue T) {
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
|
||||
}
|
||||
|
||||
|
||||
/// ReplaceUses - replace all uses of the old nodes F with the use
|
||||
/// of the new nodes T.
|
||||
void ReplaceUses(const SDValue *F, const SDValue *T, unsigned Num) {
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU);
|
||||
}
|
||||
|
||||
|
||||
/// ReplaceUses - replace all uses of the old node F with the use
|
||||
/// of the new node T.
|
||||
void ReplaceUses(SDNode *F, SDNode *T) {
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->ReplaceAllUsesWith(F, T, &ISU);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
|
||||
/// by tblgen. Others should not call it.
|
||||
void SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops);
|
||||
|
||||
|
||||
|
||||
public:
|
||||
// Calls to these predicates are generated by tblgen.
|
||||
bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
|
||||
int64_t DesiredMaskS) const;
|
||||
bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
|
||||
int64_t DesiredMaskS) const;
|
||||
|
||||
|
||||
|
||||
|
||||
/// CheckPatternPredicate - This function is generated by tblgen in the
|
||||
/// target. It runs the specified pattern predicate and returns true if it
|
||||
/// succeeds or false if it fails. The number is a private implementation
|
||||
@ -253,14 +253,14 @@ public:
|
||||
assert(0 && "Tblgen should generate the implementation of this!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual bool CheckComplexPattern(SDNode *Root, SDNode *Parent, SDValue N,
|
||||
unsigned PatternNo,
|
||||
SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) {
|
||||
assert(0 && "Tblgen should generate the implementation of this!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {
|
||||
assert(0 && "Tblgen shoudl generate this!");
|
||||
return SDValue();
|
||||
@ -269,9 +269,9 @@ public:
|
||||
SDNode *SelectCodeCommon(SDNode *NodeToMatch,
|
||||
const unsigned char *MatcherTable,
|
||||
unsigned TableSize);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
// Calls to these functions are generated by tblgen.
|
||||
SDNode *Select_INLINEASM(SDNode *N);
|
||||
SDNode *Select_UNDEF(SDNode *N);
|
||||
@ -281,7 +281,7 @@ private:
|
||||
void DoInstructionSelection();
|
||||
SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
|
||||
const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo);
|
||||
|
||||
|
||||
void PrepareEHLandingPad();
|
||||
void SelectAllBasicBlocks(const Function &Fn);
|
||||
bool TryToFoldFastISelLoad(const LoadInst *LI, FastISel *FastIS);
|
||||
@ -292,7 +292,7 @@ private:
|
||||
bool &HadTailCall);
|
||||
void CodeGenAndEmitDAG();
|
||||
void LowerArguments(const BasicBlock *BB);
|
||||
|
||||
|
||||
void ComputeLiveOutVRegInfo();
|
||||
|
||||
/// Create the scheduler. If a specific scheduler was specified
|
||||
@ -300,16 +300,16 @@ private:
|
||||
/// one preferred by the target.
|
||||
///
|
||||
ScheduleDAGSDNodes *CreateScheduler();
|
||||
|
||||
|
||||
/// OpcodeOffset - This is a cache used to dispatch efficiently into isel
|
||||
/// state machines that start with a OPC_SwitchOpcode node.
|
||||
std::vector<unsigned> OpcodeOffset;
|
||||
|
||||
|
||||
void UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain,
|
||||
const SmallVectorImpl<SDNode*> &ChainNodesMatched,
|
||||
SDValue InputGlue, const SmallVectorImpl<SDNode*> &F,
|
||||
bool isMorphNodeTo);
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ public:
|
||||
int &FrameIndex) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// isStoreToStackSlot - If the specified machine instruction is a direct
|
||||
/// store to a stack slot, return the virtual or physical register number of
|
||||
/// the source reg along with the FrameIndex of the loaded stack slot. If
|
||||
@ -267,7 +267,7 @@ public:
|
||||
/// This is only invoked in cases where AnalyzeBranch returns success. It
|
||||
/// returns the number of instructions that were removed.
|
||||
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const {
|
||||
assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!");
|
||||
assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -285,7 +285,7 @@ public:
|
||||
MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond,
|
||||
DebugLoc DL) const {
|
||||
assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
|
||||
assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -314,7 +314,7 @@ public:
|
||||
float Probability, float Confidence) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one
|
||||
/// checks for the case where two basic blocks from true and false path
|
||||
/// of a if-then-else (diamond) are predicated on mutally exclusive
|
||||
@ -341,7 +341,7 @@ public:
|
||||
float Probability, float Confidence) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// copyPhysReg - Emit instructions to copy a pair of physical registers.
|
||||
virtual void copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI, DebugLoc DL,
|
||||
@ -485,7 +485,7 @@ public:
|
||||
unsigned NumLoads) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// ReverseBranchCondition - Reverses the branch condition of the specified
|
||||
/// condition list, returning false on success and true if it cannot be
|
||||
/// reversed.
|
||||
@ -493,19 +493,19 @@ public:
|
||||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// insertNoop - Insert a noop into the instruction stream at the specified
|
||||
/// point.
|
||||
virtual void insertNoop(MachineBasicBlock &MBB,
|
||||
virtual void insertNoop(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const;
|
||||
|
||||
|
||||
|
||||
|
||||
/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
|
||||
virtual void getNoopForMachoTarget(MCInst &NopInst) const {
|
||||
// Default to just using 'nop' string.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// isPredicated - Returns true if the instruction is already predicated.
|
||||
///
|
||||
virtual bool isPredicated(const MachineInstr *MI) const {
|
||||
@ -585,7 +585,7 @@ public:
|
||||
const MachineRegisterInfo *MRI) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// FoldImmediate - 'Reg' is known to be defined by a move immediate
|
||||
/// instruction, try to fold the immediate into the use instruction.
|
||||
virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
|
||||
|
@ -121,7 +121,7 @@ public:
|
||||
InstrItineraryData(const InstrStage *S, const unsigned *OS,
|
||||
const unsigned *F, const InstrItinerary *I)
|
||||
: Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I) {}
|
||||
|
||||
|
||||
/// isEmpty - Returns true if there are no itineraries.
|
||||
///
|
||||
bool isEmpty() const { return Itineraries == 0; }
|
||||
@ -135,14 +135,14 @@ public:
|
||||
}
|
||||
|
||||
/// beginStage - Return the first stage of the itinerary.
|
||||
///
|
||||
///
|
||||
const InstrStage *beginStage(unsigned ItinClassIndx) const {
|
||||
unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
|
||||
return Stages + StageIdx;
|
||||
}
|
||||
|
||||
/// endStage - Return the last+1 stage of the itinerary.
|
||||
///
|
||||
///
|
||||
const InstrStage *endStage(unsigned ItinClassIndx) const {
|
||||
unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
|
||||
return Stages + StageIdx;
|
||||
|
@ -35,14 +35,14 @@ bool latency_sort::operator()(const SUnit *LHS, const SUnit *RHS) const {
|
||||
unsigned RHSLatency = PQ->getLatency(RHSNum);
|
||||
if (LHSLatency < RHSLatency) return true;
|
||||
if (LHSLatency > RHSLatency) return false;
|
||||
|
||||
|
||||
// After that, if two nodes have identical latencies, look to see if one will
|
||||
// unblock more other nodes than the other.
|
||||
unsigned LHSBlocked = PQ->getNumSolelyBlockNodes(LHSNum);
|
||||
unsigned RHSBlocked = PQ->getNumSolelyBlockNodes(RHSNum);
|
||||
if (LHSBlocked < RHSBlocked) return true;
|
||||
if (LHSBlocked > RHSBlocked) return false;
|
||||
|
||||
|
||||
// Finally, just to provide a stable ordering, use the node number as a
|
||||
// deciding factor.
|
||||
return LHSNum < RHSNum;
|
||||
@ -64,7 +64,7 @@ SUnit *LatencyPriorityQueue::getSingleUnscheduledPred(SUnit *SU) {
|
||||
OnlyAvailablePred = &Pred;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return OnlyAvailablePred;
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ void LatencyPriorityQueue::push(SUnit *SU) {
|
||||
++NumNodesBlocking;
|
||||
}
|
||||
NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking;
|
||||
|
||||
|
||||
Queue.push_back(SU);
|
||||
}
|
||||
|
||||
@ -102,10 +102,10 @@ void LatencyPriorityQueue::ScheduledNode(SUnit *SU) {
|
||||
/// node of the same priority that will not make a node available.
|
||||
void LatencyPriorityQueue::AdjustPriorityOfUnscheduledPreds(SUnit *SU) {
|
||||
if (SU->isAvailable) return; // All preds scheduled.
|
||||
|
||||
|
||||
SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);
|
||||
if (OnlyAvailablePred == 0 || !OnlyAvailablePred->isAvailable) return;
|
||||
|
||||
|
||||
// Okay, we found a single predecessor that is available, but not scheduled.
|
||||
// Since it is available, it must be in the priority queue. First remove it.
|
||||
remove(OnlyAvailablePred);
|
||||
|
@ -40,7 +40,7 @@ STATISTIC(NumStalls, "Number of pipeline stalls");
|
||||
static RegisterScheduler
|
||||
tdListDAGScheduler("list-td", "Top-down list scheduler",
|
||||
createTDListDAGScheduler);
|
||||
|
||||
|
||||
namespace {
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// ScheduleDAGList - The actual list scheduler implementation. This supports
|
||||
@ -51,7 +51,7 @@ private:
|
||||
/// AvailableQueue - The priority queue to use for the available SUnits.
|
||||
///
|
||||
SchedulingPriorityQueue *AvailableQueue;
|
||||
|
||||
|
||||
/// PendingQueue - This contains all of the instructions whose operands have
|
||||
/// been issued, but their results are not ready yet (due to the latency of
|
||||
/// the operation). Once the operands become available, the instruction is
|
||||
@ -87,14 +87,14 @@ private:
|
||||
/// Schedule - Schedule the DAG using list scheduling.
|
||||
void ScheduleDAGList::Schedule() {
|
||||
DEBUG(dbgs() << "********** List Scheduling **********\n");
|
||||
|
||||
|
||||
// Build the scheduling graph.
|
||||
BuildSchedGraph(NULL);
|
||||
|
||||
AvailableQueue->initNodes(SUnits);
|
||||
|
||||
|
||||
ListScheduleTopDown();
|
||||
|
||||
|
||||
AvailableQueue->releaseState();
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ void ScheduleDAGList::ReleaseSucc(SUnit *SU, const SDep &D) {
|
||||
--SuccSU->NumPredsLeft;
|
||||
|
||||
SuccSU->setDepthToAtLeast(SU->getDepth() + D.getLatency());
|
||||
|
||||
|
||||
// If all the node's predecessors are scheduled, this node is ready
|
||||
// to be scheduled. Ignore the special ExitSU node.
|
||||
if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU)
|
||||
@ -142,7 +142,7 @@ void ScheduleDAGList::ReleaseSuccessors(SUnit *SU) {
|
||||
void ScheduleDAGList::ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle) {
|
||||
DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: ");
|
||||
DEBUG(SU->dump(this));
|
||||
|
||||
|
||||
Sequence.push_back(SU);
|
||||
assert(CurCycle >= SU->getDepth() && "Node scheduled above its depth!");
|
||||
SU->setDepthToAtLeast(CurCycle);
|
||||
@ -168,7 +168,7 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
||||
SUnits[i].isAvailable = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// While Available queue is not empty, grab the node with the highest
|
||||
// priority. If it is not ready put it back. Schedule the node.
|
||||
std::vector<SUnit*> NotReady;
|
||||
@ -187,7 +187,7 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
||||
assert(PendingQueue[i]->getDepth() > CurCycle && "Negative latency?");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If there are no instructions available, don't try to issue anything, and
|
||||
// don't advance the hazard recognizer.
|
||||
if (AvailableQueue->empty()) {
|
||||
@ -196,24 +196,24 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
||||
}
|
||||
|
||||
SUnit *FoundSUnit = 0;
|
||||
|
||||
|
||||
bool HasNoopHazards = false;
|
||||
while (!AvailableQueue->empty()) {
|
||||
SUnit *CurSUnit = AvailableQueue->pop();
|
||||
|
||||
|
||||
ScheduleHazardRecognizer::HazardType HT =
|
||||
HazardRec->getHazardType(CurSUnit);
|
||||
if (HT == ScheduleHazardRecognizer::NoHazard) {
|
||||
FoundSUnit = CurSUnit;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Remember if this is a noop hazard.
|
||||
HasNoopHazards |= HT == ScheduleHazardRecognizer::NoopHazard;
|
||||
|
||||
|
||||
NotReady.push_back(CurSUnit);
|
||||
}
|
||||
|
||||
|
||||
// Add the nodes that aren't ready back onto the available list.
|
||||
if (!NotReady.empty()) {
|
||||
AvailableQueue->push_all(NotReady);
|
||||
@ -228,7 +228,7 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
||||
// If this is a pseudo-op node, we don't want to increment the current
|
||||
// cycle.
|
||||
if (FoundSUnit->Latency) // Don't increment CurCycle for pseudo-ops!
|
||||
++CurCycle;
|
||||
++CurCycle;
|
||||
} else if (!HasNoopHazards) {
|
||||
// Otherwise, we have a pipeline stall, but no other problem, just advance
|
||||
// the current cycle and try again.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1687,7 +1687,7 @@ ARMBaseInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
|
||||
|
||||
// The number of uOps for load / store multiple are determined by the number
|
||||
// registers.
|
||||
//
|
||||
//
|
||||
// On Cortex-A8, each pair of register loads / stores can be scheduled on the
|
||||
// same cycle. The scheduling for the first load / store must be done
|
||||
// separately by assuming the the address is not 64-bit aligned.
|
||||
|
@ -2039,7 +2039,7 @@ SelectARMCMOVImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
|
||||
SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
|
||||
return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV,
|
||||
// through a stub.
|
||||
if (!isDecl && !GV->isWeakForLinker())
|
||||
return false;
|
||||
|
||||
|
||||
// Unless we have a symbol with hidden visibility, we have to go through a
|
||||
// normal $non_lazy_ptr stub because this symbol might be resolved late.
|
||||
if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference.
|
||||
@ -219,7 +219,7 @@ unsigned ARMSubtarget::getMispredictionPenalty() const {
|
||||
return 13;
|
||||
else if (isCortexA9())
|
||||
return 8;
|
||||
|
||||
|
||||
// Otherwise, just return a sensible default.
|
||||
return 10;
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ protected:
|
||||
const std::string & getCPUString() const { return CPUString; }
|
||||
|
||||
unsigned getMispredictionPenalty() const;
|
||||
|
||||
|
||||
/// enablePostRAScheduler - True at 'More' optimization.
|
||||
bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,
|
||||
TargetSubtarget::AntiDepBreakMode& Mode,
|
||||
|
@ -20,7 +20,7 @@
|
||||
namespace llvm {
|
||||
|
||||
class TargetInstrInfo;
|
||||
|
||||
|
||||
/// SPUHazardRecognizer
|
||||
class SPUHazardRecognizer : public ScheduleHazardRecognizer
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ using namespace llvm;
|
||||
//
|
||||
// This models the dispatch group formation of the PPC970 processor. Dispatch
|
||||
// groups are bundles of up to five instructions that can contain various mixes
|
||||
// of instructions. The PPC970 can dispatch a peak of 4 non-branch and one
|
||||
// of instructions. The PPC970 can dispatch a peak of 4 non-branch and one
|
||||
// branch instruction per-cycle.
|
||||
//
|
||||
// There are a number of restrictions to dispatch group formation: some
|
||||
@ -55,14 +55,14 @@ PPCHazardRecognizer970::PPCHazardRecognizer970(const TargetInstrInfo &tii)
|
||||
void PPCHazardRecognizer970::EndDispatchGroup() {
|
||||
DEBUG(errs() << "=== Start of dispatch group\n");
|
||||
NumIssued = 0;
|
||||
|
||||
|
||||
// Structural hazard info.
|
||||
HasCTRSet = false;
|
||||
NumStores = 0;
|
||||
}
|
||||
|
||||
|
||||
PPCII::PPC970_Unit
|
||||
PPCII::PPC970_Unit
|
||||
PPCHazardRecognizer970::GetInstrType(unsigned Opcode,
|
||||
bool &isFirst, bool &isSingle,
|
||||
bool &isCracked,
|
||||
@ -72,14 +72,14 @@ PPCHazardRecognizer970::GetInstrType(unsigned Opcode,
|
||||
return PPCII::PPC970_Pseudo;
|
||||
}
|
||||
Opcode = ~Opcode;
|
||||
|
||||
|
||||
const TargetInstrDesc &TID = TII.get(Opcode);
|
||||
|
||||
|
||||
isLoad = TID.mayLoad();
|
||||
isStore = TID.mayStore();
|
||||
|
||||
|
||||
uint64_t TSFlags = TID.TSFlags;
|
||||
|
||||
|
||||
isFirst = TSFlags & PPCII::PPC970_First;
|
||||
isSingle = TSFlags & PPCII::PPC970_Single;
|
||||
isCracked = TSFlags & PPCII::PPC970_Cracked;
|
||||
@ -96,7 +96,7 @@ isLoadOfStoredAddress(unsigned LoadSize, SDValue Ptr1, SDValue Ptr2) const {
|
||||
return true;
|
||||
if (Ptr2 == StorePtr1[i] && Ptr1 == StorePtr2[i])
|
||||
return true;
|
||||
|
||||
|
||||
// Okay, we don't have an exact match, if this is an indexed offset, see if
|
||||
// we have overlap (which happens during fp->int conversion for example).
|
||||
if (StorePtr2[i] == Ptr2) {
|
||||
@ -125,23 +125,23 @@ ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970::
|
||||
getHazardType(SUnit *SU) {
|
||||
const SDNode *Node = SU->getNode()->getGluedMachineNode();
|
||||
bool isFirst, isSingle, isCracked, isLoad, isStore;
|
||||
PPCII::PPC970_Unit InstrType =
|
||||
PPCII::PPC970_Unit InstrType =
|
||||
GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked,
|
||||
isLoad, isStore);
|
||||
if (InstrType == PPCII::PPC970_Pseudo) return NoHazard;
|
||||
if (InstrType == PPCII::PPC970_Pseudo) return NoHazard;
|
||||
unsigned Opcode = Node->getMachineOpcode();
|
||||
|
||||
// We can only issue a PPC970_First/PPC970_Single instruction (such as
|
||||
// crand/mtspr/etc) if this is the first cycle of the dispatch group.
|
||||
if (NumIssued != 0 && (isFirst || isSingle))
|
||||
return Hazard;
|
||||
|
||||
|
||||
// If this instruction is cracked into two ops by the decoder, we know that
|
||||
// it is not a branch and that it cannot issue if 3 other instructions are
|
||||
// already in the dispatch group.
|
||||
if (isCracked && NumIssued > 2)
|
||||
return Hazard;
|
||||
|
||||
|
||||
switch (InstrType) {
|
||||
default: llvm_unreachable("Unknown instruction type!");
|
||||
case PPCII::PPC970_FXU:
|
||||
@ -159,11 +159,11 @@ getHazardType(SUnit *SU) {
|
||||
case PPCII::PPC970_BRU:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Do not allow MTCTR and BCTRL to be in the same dispatch group.
|
||||
if (HasCTRSet && (Opcode == PPC::BCTRL_Darwin || Opcode == PPC::BCTRL_SVR4))
|
||||
return NoopHazard;
|
||||
|
||||
|
||||
// If this is a load following a store, make sure it's not to the same or
|
||||
// overlapping address.
|
||||
if (isLoad && NumStores) {
|
||||
@ -212,27 +212,27 @@ getHazardType(SUnit *SU) {
|
||||
LoadSize = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isLoadOfStoredAddress(LoadSize,
|
||||
|
||||
if (isLoadOfStoredAddress(LoadSize,
|
||||
Node->getOperand(0), Node->getOperand(1)))
|
||||
return NoopHazard;
|
||||
}
|
||||
|
||||
|
||||
return NoHazard;
|
||||
}
|
||||
|
||||
void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
|
||||
const SDNode *Node = SU->getNode()->getGluedMachineNode();
|
||||
bool isFirst, isSingle, isCracked, isLoad, isStore;
|
||||
PPCII::PPC970_Unit InstrType =
|
||||
PPCII::PPC970_Unit InstrType =
|
||||
GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked,
|
||||
isLoad, isStore);
|
||||
if (InstrType == PPCII::PPC970_Pseudo) return;
|
||||
if (InstrType == PPCII::PPC970_Pseudo) return;
|
||||
unsigned Opcode = Node->getMachineOpcode();
|
||||
|
||||
// Update structural hazard information.
|
||||
if (Opcode == PPC::MTCTR) HasCTRSet = true;
|
||||
|
||||
|
||||
// Track the address stored to.
|
||||
if (isStore) {
|
||||
unsigned ThisStoreSize;
|
||||
@ -278,22 +278,22 @@ void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
|
||||
ThisStoreSize = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
StoreSize[NumStores] = ThisStoreSize;
|
||||
StorePtr1[NumStores] = Node->getOperand(1);
|
||||
StorePtr2[NumStores] = Node->getOperand(2);
|
||||
++NumStores;
|
||||
}
|
||||
|
||||
|
||||
if (InstrType == PPCII::PPC970_BRU || isSingle)
|
||||
NumIssued = 4; // Terminate a d-group.
|
||||
++NumIssued;
|
||||
|
||||
|
||||
// If this instruction is cracked into two ops by the decoder, remember that
|
||||
// we issued two pieces.
|
||||
if (isCracked)
|
||||
++NumIssued;
|
||||
|
||||
|
||||
if (NumIssued == 5)
|
||||
EndDispatchGroup();
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "PPCInstrInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
||||
/// PPCHazardRecognizer970 - This class defines a finite state automata that
|
||||
/// models the dispatch logic on the PowerPC 970 (aka G5) processor. This
|
||||
/// promotes good dispatch group formation and implements noop insertion to
|
||||
@ -28,14 +28,14 @@ namespace llvm {
|
||||
/// or storing then loading from the same address within a dispatch group.
|
||||
class PPCHazardRecognizer970 : public ScheduleHazardRecognizer {
|
||||
const TargetInstrInfo &TII;
|
||||
|
||||
|
||||
unsigned NumIssued; // Number of insts issued, including advanced cycles.
|
||||
|
||||
|
||||
// Various things that can cause a structural hazard.
|
||||
|
||||
|
||||
// HasCTRSet - If the CTR register is set in this group, disallow BCTRL.
|
||||
bool HasCTRSet;
|
||||
|
||||
|
||||
// StoredPtr - Keep track of the address of any store. If we see a load from
|
||||
// the same address (or one that aliases it), disallow the store. We can have
|
||||
// up to four stores in one dispatch group, hence we track up to 4.
|
||||
@ -45,24 +45,24 @@ class PPCHazardRecognizer970 : public ScheduleHazardRecognizer {
|
||||
SDValue StorePtr1[4], StorePtr2[4];
|
||||
unsigned StoreSize[4];
|
||||
unsigned NumStores;
|
||||
|
||||
|
||||
public:
|
||||
PPCHazardRecognizer970(const TargetInstrInfo &TII);
|
||||
virtual HazardType getHazardType(SUnit *SU);
|
||||
virtual void EmitInstruction(SUnit *SU);
|
||||
virtual void AdvanceCycle();
|
||||
|
||||
|
||||
private:
|
||||
/// EndDispatchGroup - Called when we are finishing a new dispatch group.
|
||||
///
|
||||
void EndDispatchGroup();
|
||||
|
||||
|
||||
/// GetInstrType - Classify the specified powerpc opcode according to its
|
||||
/// pipeline.
|
||||
PPCII::PPC970_Unit GetInstrType(unsigned Opcode,
|
||||
bool &isFirst, bool &isSingle,bool &isCracked,
|
||||
bool &isLoad, bool &isStore);
|
||||
|
||||
|
||||
bool isLoadOfStoredAddress(unsigned LoadSize,
|
||||
SDValue Ptr1, SDValue Ptr2) const;
|
||||
};
|
||||
|
@ -49,16 +49,16 @@ namespace {
|
||||
: SelectionDAGISel(tm), TM(tm),
|
||||
PPCLowering(*TM.getTargetLowering()),
|
||||
PPCSubTarget(*TM.getSubtargetImpl()) {}
|
||||
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &MF) {
|
||||
// Make sure we re-emit a set of the global base reg if necessary
|
||||
GlobalBaseReg = 0;
|
||||
SelectionDAGISel::runOnMachineFunction(MF);
|
||||
|
||||
|
||||
InsertVRSaveCode(MF);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// getI32Imm - Return a target constant with the specified value, of type
|
||||
/// i32.
|
||||
inline SDValue getI32Imm(unsigned Imm) {
|
||||
@ -70,13 +70,13 @@ namespace {
|
||||
inline SDValue getI64Imm(uint64_t Imm) {
|
||||
return CurDAG->getTargetConstant(Imm, MVT::i64);
|
||||
}
|
||||
|
||||
|
||||
/// getSmallIPtrImm - Return a target constant of pointer type.
|
||||
inline SDValue getSmallIPtrImm(unsigned Imm) {
|
||||
return CurDAG->getTargetConstant(Imm, PPCLowering.getPointerTy());
|
||||
}
|
||||
|
||||
/// isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s
|
||||
|
||||
/// isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s
|
||||
/// with any number of 0s on either side. The 1s are allowed to wrap from
|
||||
/// LSB to MSB, so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs.
|
||||
/// 0x0F0F0000 is not, since all 1s are not contiguous.
|
||||
@ -87,15 +87,15 @@ namespace {
|
||||
/// rotate and mask opcode and mask operation.
|
||||
static bool isRotateAndMask(SDNode *N, unsigned Mask, bool isShiftMask,
|
||||
unsigned &SH, unsigned &MB, unsigned &ME);
|
||||
|
||||
|
||||
/// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
|
||||
/// base register. Return the virtual register that holds this value.
|
||||
SDNode *getGlobalBaseReg();
|
||||
|
||||
|
||||
// Select - Convert the specified operand from a target-independent to a
|
||||
// target-specific node if it hasn't already been changed.
|
||||
SDNode *Select(SDNode *N);
|
||||
|
||||
|
||||
SDNode *SelectBitfieldInsert(SDNode *N);
|
||||
|
||||
/// SelectCC - Select a comparison of the specified values with the
|
||||
@ -108,7 +108,7 @@ namespace {
|
||||
SDValue &Base) {
|
||||
return PPCLowering.SelectAddressRegImm(N, Disp, Base, *CurDAG);
|
||||
}
|
||||
|
||||
|
||||
/// SelectAddrImmOffs - Return true if the operand is valid for a preinc
|
||||
/// immediate field. Because preinc imms have already been validated, just
|
||||
/// accept it.
|
||||
@ -116,14 +116,14 @@ namespace {
|
||||
Out = N;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// SelectAddrIdx - Given the specified addressed, check to see if it can be
|
||||
/// represented as an indexed [r+r] operation. Returns false if it can
|
||||
/// be represented by [r+imm], which are preferred.
|
||||
bool SelectAddrIdx(SDValue N, SDValue &Base, SDValue &Index) {
|
||||
return PPCLowering.SelectAddressRegReg(N, Base, Index, *CurDAG);
|
||||
}
|
||||
|
||||
|
||||
/// SelectAddrIdxOnly - Given the specified addressed, force it to be
|
||||
/// represented as an indexed [r+r] operation.
|
||||
bool SelectAddrIdxOnly(SDValue N, SDValue &Base, SDValue &Index) {
|
||||
@ -136,7 +136,7 @@ namespace {
|
||||
bool SelectAddrImmShift(SDValue N, SDValue &Disp, SDValue &Base) {
|
||||
return PPCLowering.SelectAddressRegImmShift(N, Disp, Base, *CurDAG);
|
||||
}
|
||||
|
||||
|
||||
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
|
||||
/// inline asm expressions. It is always correct to compute the value into
|
||||
/// a register. The case of adding a (possibly relocatable) constant to a
|
||||
@ -148,13 +148,13 @@ namespace {
|
||||
OutOps.push_back(Op);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void InsertVRSaveCode(MachineFunction &MF);
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "PowerPC DAG->DAG Pattern Instruction Selection";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
|
||||
/// this target when scheduling the DAG.
|
||||
virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() {
|
||||
@ -162,12 +162,12 @@ namespace {
|
||||
// now, always return a PPC970 recognizer.
|
||||
const TargetInstrInfo *II = TM.getInstrInfo();
|
||||
assert(II && "No InstrInfo?");
|
||||
return new PPCHazardRecognizer970(*II);
|
||||
return new PPCHazardRecognizer970(*II);
|
||||
}
|
||||
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#include "PPCGenDAGISel.inc"
|
||||
|
||||
|
||||
private:
|
||||
SDNode *SelectSETCC(SDNode *N);
|
||||
};
|
||||
@ -178,19 +178,19 @@ private:
|
||||
/// check to see if we need to save/restore VRSAVE. If so, do it.
|
||||
void PPCDAGToDAGISel::InsertVRSaveCode(MachineFunction &Fn) {
|
||||
// Check to see if this function uses vector registers, which means we have to
|
||||
// save and restore the VRSAVE register and update it with the regs we use.
|
||||
// save and restore the VRSAVE register and update it with the regs we use.
|
||||
//
|
||||
// In this case, there will be virtual registers of vector type created
|
||||
// by the scheduler. Detect them now.
|
||||
bool HasVectorVReg = false;
|
||||
for (unsigned i = TargetRegisterInfo::FirstVirtualRegister,
|
||||
for (unsigned i = TargetRegisterInfo::FirstVirtualRegister,
|
||||
e = RegInfo->getLastVirtReg()+1; i != e; ++i)
|
||||
if (RegInfo->getRegClass(i) == &PPC::VRRCRegClass) {
|
||||
HasVectorVReg = true;
|
||||
break;
|
||||
}
|
||||
if (!HasVectorVReg) return; // nothing to do.
|
||||
|
||||
|
||||
// If we have a vector register, we want to emit code into the entry and exit
|
||||
// blocks to save and restore the VRSAVE register. We do this here (instead
|
||||
// of marking all vector instructions as clobbering VRSAVE) for two reasons:
|
||||
@ -205,7 +205,7 @@ void PPCDAGToDAGISel::InsertVRSaveCode(MachineFunction &Fn) {
|
||||
// function and one for the value after having bits or'd into it.
|
||||
unsigned InVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
|
||||
unsigned UpdatedVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
|
||||
|
||||
|
||||
const TargetInstrInfo &TII = *TM.getInstrInfo();
|
||||
MachineBasicBlock &EntryBB = *Fn.begin();
|
||||
DebugLoc dl;
|
||||
@ -218,21 +218,21 @@ void PPCDAGToDAGISel::InsertVRSaveCode(MachineFunction &Fn) {
|
||||
BuildMI(EntryBB, IP, dl, TII.get(PPC::UPDATE_VRSAVE),
|
||||
UpdatedVRSAVE).addReg(InVRSAVE);
|
||||
BuildMI(EntryBB, IP, dl, TII.get(PPC::MTVRSAVE)).addReg(UpdatedVRSAVE);
|
||||
|
||||
|
||||
// Find all return blocks, outputting a restore in each epilog.
|
||||
for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
|
||||
if (!BB->empty() && BB->back().getDesc().isReturn()) {
|
||||
IP = BB->end(); --IP;
|
||||
|
||||
|
||||
// Skip over all terminator instructions, which are part of the return
|
||||
// sequence.
|
||||
MachineBasicBlock::iterator I2 = IP;
|
||||
while (I2 != BB->begin() && (--I2)->getDesc().isTerminator())
|
||||
IP = I2;
|
||||
|
||||
|
||||
// Emit: MTVRSAVE InVRSave
|
||||
BuildMI(*BB, IP, dl, TII.get(PPC::MTVRSAVE)).addReg(InVRSAVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,8 +338,8 @@ bool PPCDAGToDAGISel::isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PPCDAGToDAGISel::isRotateAndMask(SDNode *N, unsigned Mask,
|
||||
bool isShiftMask, unsigned &SH,
|
||||
bool PPCDAGToDAGISel::isRotateAndMask(SDNode *N, unsigned Mask,
|
||||
bool isShiftMask, unsigned &SH,
|
||||
unsigned &MB, unsigned &ME) {
|
||||
// Don't even go down this path for i64, since different logic will be
|
||||
// necessary for rldicl/rldicr/rldimi.
|
||||
@ -352,13 +352,13 @@ bool PPCDAGToDAGISel::isRotateAndMask(SDNode *N, unsigned Mask,
|
||||
if (N->getNumOperands() != 2 ||
|
||||
!isInt32Immediate(N->getOperand(1).getNode(), Shift) || (Shift > 31))
|
||||
return false;
|
||||
|
||||
|
||||
if (Opcode == ISD::SHL) {
|
||||
// apply shift left to mask if it comes first
|
||||
if (isShiftMask) Mask = Mask << Shift;
|
||||
// determine which bits are made indeterminant by shift
|
||||
Indeterminant = ~(0xFFFFFFFFu << Shift);
|
||||
} else if (Opcode == ISD::SRL) {
|
||||
} else if (Opcode == ISD::SRL) {
|
||||
// apply shift right to mask if it comes first
|
||||
if (isShiftMask) Mask = Mask >> Shift;
|
||||
// determine which bits are made indeterminant by shift
|
||||
@ -370,7 +370,7 @@ bool PPCDAGToDAGISel::isRotateAndMask(SDNode *N, unsigned Mask,
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// if the mask doesn't intersect any Indeterminant bits
|
||||
if (Mask && !(Mask & Indeterminant)) {
|
||||
SH = Shift & 31;
|
||||
@ -386,14 +386,14 @@ SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) {
|
||||
SDValue Op0 = N->getOperand(0);
|
||||
SDValue Op1 = N->getOperand(1);
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
|
||||
|
||||
APInt LKZ, LKO, RKZ, RKO;
|
||||
CurDAG->ComputeMaskedBits(Op0, APInt::getAllOnesValue(32), LKZ, LKO);
|
||||
CurDAG->ComputeMaskedBits(Op1, APInt::getAllOnesValue(32), RKZ, RKO);
|
||||
|
||||
|
||||
unsigned TargetMask = LKZ.getZExtValue();
|
||||
unsigned InsertMask = RKZ.getZExtValue();
|
||||
|
||||
|
||||
if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
|
||||
unsigned Op0Opc = Op0.getOpcode();
|
||||
unsigned Op1Opc = Op1.getOpcode();
|
||||
@ -421,7 +421,7 @@ SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) {
|
||||
std::swap(TargetMask, InsertMask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned MB, ME;
|
||||
if (InsertMask && isRunOfOnes(InsertMask, MB, ME)) {
|
||||
SDValue Tmp1, Tmp2;
|
||||
@ -457,7 +457,7 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS,
|
||||
ISD::CondCode CC, DebugLoc dl) {
|
||||
// Always select the LHS.
|
||||
unsigned Opc;
|
||||
|
||||
|
||||
if (LHS.getValueType() == MVT::i32) {
|
||||
unsigned Imm;
|
||||
if (CC == ISD::SETEQ || CC == ISD::SETNE) {
|
||||
@ -470,11 +470,11 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS,
|
||||
if (isInt<16>((int)Imm))
|
||||
return SDValue(CurDAG->getMachineNode(PPC::CMPWI, dl, MVT::i32, LHS,
|
||||
getI32Imm(Imm & 0xFFFF)), 0);
|
||||
|
||||
|
||||
// For non-equality comparisons, the default code would materialize the
|
||||
// constant, then compare against it, like this:
|
||||
// lis r2, 4660
|
||||
// ori r2, r2, 22136
|
||||
// ori r2, r2, 22136
|
||||
// cmpw cr0, r3, r2
|
||||
// Since we are just comparing for equality, we can emit this instead:
|
||||
// xoris r0,r3,0x1234
|
||||
@ -511,11 +511,11 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS,
|
||||
if (isInt<16>(Imm))
|
||||
return SDValue(CurDAG->getMachineNode(PPC::CMPDI, dl, MVT::i64, LHS,
|
||||
getI32Imm(Imm & 0xFFFF)), 0);
|
||||
|
||||
|
||||
// For non-equality comparisons, the default code would materialize the
|
||||
// constant, then compare against it, like this:
|
||||
// lis r2, 4660
|
||||
// ori r2, r2, 22136
|
||||
// ori r2, r2, 22136
|
||||
// cmpd cr0, r3, r2
|
||||
// Since we are just comparing for equality, we can emit this instead:
|
||||
// xoris r0,r3,0x1234
|
||||
@ -604,9 +604,9 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert, int &Other) {
|
||||
case ISD::SETUNE:
|
||||
case ISD::SETNE: Invert = true; return 2; // !Bit #2 = SETUNE
|
||||
case ISD::SETO: Invert = true; return 3; // !Bit #3 = SETO
|
||||
case ISD::SETUEQ:
|
||||
case ISD::SETOGE:
|
||||
case ISD::SETOLE:
|
||||
case ISD::SETUEQ:
|
||||
case ISD::SETOGE:
|
||||
case ISD::SETOLE:
|
||||
case ISD::SETONE:
|
||||
llvm_unreachable("Invalid branch code: should be expanded by legalize");
|
||||
// These are invalid for floating point. Assume integer.
|
||||
@ -637,7 +637,7 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
|
||||
SDValue AD =
|
||||
SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue,
|
||||
Op, getI32Imm(~0U)), 0);
|
||||
return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op,
|
||||
return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op,
|
||||
AD.getValue(1));
|
||||
}
|
||||
case ISD::SETLT: {
|
||||
@ -659,8 +659,8 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
|
||||
case ISD::SETEQ:
|
||||
Op = SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue,
|
||||
Op, getI32Imm(1)), 0);
|
||||
return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,
|
||||
SDValue(CurDAG->getMachineNode(PPC::LI, dl,
|
||||
return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,
|
||||
SDValue(CurDAG->getMachineNode(PPC::LI, dl,
|
||||
MVT::i32,
|
||||
getI32Imm(0)), 0),
|
||||
Op.getValue(1));
|
||||
@ -681,35 +681,35 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
|
||||
}
|
||||
case ISD::SETGT: {
|
||||
SDValue Ops[] = { Op, getI32Imm(1), getI32Imm(31), getI32Imm(31) };
|
||||
Op = SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops, 4),
|
||||
Op = SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops, 4),
|
||||
0);
|
||||
return CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op,
|
||||
return CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op,
|
||||
getI32Imm(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Inv;
|
||||
int OtherCondIdx;
|
||||
unsigned Idx = getCRIdxForSetCC(CC, Inv, OtherCondIdx);
|
||||
SDValue CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC, dl);
|
||||
SDValue IntCR;
|
||||
|
||||
|
||||
// Force the ccreg into CR7.
|
||||
SDValue CR7Reg = CurDAG->getRegister(PPC::CR7, MVT::i32);
|
||||
|
||||
|
||||
SDValue InFlag(0, 0); // Null incoming flag value.
|
||||
CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, CR7Reg, CCReg,
|
||||
CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, CR7Reg, CCReg,
|
||||
InFlag).getValue(1);
|
||||
|
||||
|
||||
if (PPCSubTarget.isGigaProcessor() && OtherCondIdx == -1)
|
||||
IntCR = SDValue(CurDAG->getMachineNode(PPC::MFOCRF, dl, MVT::i32, CR7Reg,
|
||||
CCReg), 0);
|
||||
else
|
||||
IntCR = SDValue(CurDAG->getMachineNode(PPC::MFCRpseud, dl, MVT::i32,
|
||||
CR7Reg, CCReg), 0);
|
||||
|
||||
|
||||
SDValue Ops[] = { IntCR, getI32Imm((32-(3-Idx)) & 31),
|
||||
getI32Imm(31), getI32Imm(31) };
|
||||
if (OtherCondIdx == -1 && !Inv)
|
||||
@ -728,7 +728,7 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
|
||||
|
||||
// Get the other bit of the comparison.
|
||||
Ops[1] = getI32Imm((32-(3-OtherCondIdx)) & 31);
|
||||
SDValue OtherCond =
|
||||
SDValue OtherCond =
|
||||
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), 0);
|
||||
|
||||
return CurDAG->SelectNodeTo(N, PPC::OR, MVT::i32, Tmp, OtherCond);
|
||||
@ -744,7 +744,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
default: break;
|
||||
|
||||
|
||||
case ISD::Constant: {
|
||||
if (N->getValueType(0) == MVT::i64) {
|
||||
// Get 64 bit value.
|
||||
@ -753,12 +753,12 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
unsigned Remainder = 0;
|
||||
// Assume no shift required.
|
||||
unsigned Shift = 0;
|
||||
|
||||
|
||||
// If it can't be represented as a 32 bit value.
|
||||
if (!isInt<32>(Imm)) {
|
||||
Shift = CountTrailingZeros_64(Imm);
|
||||
int64_t ImmSh = static_cast<uint64_t>(Imm) >> Shift;
|
||||
|
||||
|
||||
// If the shifted value fits 32 bits.
|
||||
if (isInt<32>(ImmSh)) {
|
||||
// Go with the shifted value.
|
||||
@ -770,14 +770,14 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
Imm >>= 32;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Intermediate operand.
|
||||
SDNode *Result;
|
||||
|
||||
// Handle first 32 bits.
|
||||
unsigned Lo = Imm & 0xFFFF;
|
||||
unsigned Hi = (Imm >> 16) & 0xFFFF;
|
||||
|
||||
|
||||
// Simple value.
|
||||
if (isInt<16>(Imm)) {
|
||||
// Just the Lo bits.
|
||||
@ -793,7 +793,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
// Just the Hi bits.
|
||||
Result = CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi));
|
||||
}
|
||||
|
||||
|
||||
// If no shift, we're done.
|
||||
if (!Shift) return Result;
|
||||
|
||||
@ -809,22 +809,22 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
if ((Hi = (Remainder >> 16) & 0xFFFF)) {
|
||||
Result = CurDAG->getMachineNode(PPC::ORIS8, dl, MVT::i64,
|
||||
SDValue(Result, 0), getI32Imm(Hi));
|
||||
}
|
||||
}
|
||||
if ((Lo = Remainder & 0xFFFF)) {
|
||||
Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64,
|
||||
SDValue(Result, 0), getI32Imm(Lo));
|
||||
}
|
||||
|
||||
|
||||
return Result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case ISD::SETCC:
|
||||
return SelectSETCC(N);
|
||||
case PPCISD::GlobalBaseReg:
|
||||
return getGlobalBaseReg();
|
||||
|
||||
|
||||
case ISD::FrameIndex: {
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0));
|
||||
@ -846,11 +846,11 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
return CurDAG->getMachineNode(PPC::MFCRpseud, dl, MVT::i32,
|
||||
N->getOperand(0), InFlag);
|
||||
}
|
||||
|
||||
|
||||
case ISD::SDIV: {
|
||||
// FIXME: since this depends on the setting of the carry flag from the srawi
|
||||
// we should really be making notes about that for the scheduler.
|
||||
// FIXME: It sure would be nice if we could cheaply recognize the
|
||||
// FIXME: It sure would be nice if we could cheaply recognize the
|
||||
// srl/add/sra pattern the dag combiner will generate for this as
|
||||
// sra/addze rather than having to handle sdiv ourselves. oh well.
|
||||
unsigned Imm;
|
||||
@ -860,7 +860,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
SDNode *Op =
|
||||
CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, MVT::Glue,
|
||||
N0, getI32Imm(Log2_32(Imm)));
|
||||
return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,
|
||||
return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,
|
||||
SDValue(Op, 0), SDValue(Op, 1));
|
||||
} else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) {
|
||||
SDNode *Op =
|
||||
@ -873,24 +873,24 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
return CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case ISD::LOAD: {
|
||||
// Handle preincrement loads.
|
||||
LoadSDNode *LD = cast<LoadSDNode>(N);
|
||||
EVT LoadedVT = LD->getMemoryVT();
|
||||
|
||||
|
||||
// Normal loads are handled by code generated from the .td file.
|
||||
if (LD->getAddressingMode() != ISD::PRE_INC)
|
||||
break;
|
||||
|
||||
|
||||
SDValue Offset = LD->getOffset();
|
||||
if (isa<ConstantSDNode>(Offset) ||
|
||||
Offset.getOpcode() == ISD::TargetGlobalAddress) {
|
||||
|
||||
|
||||
unsigned Opcode;
|
||||
bool isSExt = LD->getExtensionType() == ISD::SEXTLOAD;
|
||||
if (LD->getValueType(0) != MVT::i64) {
|
||||
@ -917,7 +917,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
case MVT::i8: Opcode = PPC::LBZU8; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDValue Chain = LD->getChain();
|
||||
SDValue Base = LD->getBasePtr();
|
||||
SDValue Ops[] = { Offset, Base, Chain };
|
||||
@ -929,7 +929,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
llvm_unreachable("R+R preindex loads not supported yet!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case ISD::AND: {
|
||||
unsigned Imm, Imm2, SH, MB, ME;
|
||||
|
||||
@ -944,7 +944,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
// If this is just a masked value where the input is not handled above, and
|
||||
// is not a rotate-left (handled by a pattern in the .td file), emit rlwinm
|
||||
if (isInt32Immediate(N->getOperand(1), Imm) &&
|
||||
isRunOfOnes(Imm, MB, ME) &&
|
||||
isRunOfOnes(Imm, MB, ME) &&
|
||||
N->getOperand(0).getOpcode() != ISD::ROTL) {
|
||||
SDValue Val = N->getOperand(0);
|
||||
SDValue Ops[] = { Val, getI32Imm(0), getI32Imm(MB), getI32Imm(ME) };
|
||||
@ -957,7 +957,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
}
|
||||
// ISD::OR doesn't get all the bitfield insertion fun.
|
||||
// (and (or x, c1), c2) where isRunOfOnes(~(c1^c2)) is a bitfield insert
|
||||
if (isInt32Immediate(N->getOperand(1), Imm) &&
|
||||
if (isInt32Immediate(N->getOperand(1), Imm) &&
|
||||
N->getOperand(0).getOpcode() == ISD::OR &&
|
||||
isInt32Immediate(N->getOperand(0).getOperand(1), Imm2)) {
|
||||
unsigned MB, ME;
|
||||
@ -969,7 +969,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
return CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops, 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
@ -977,7 +977,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
if (N->getValueType(0) == MVT::i32)
|
||||
if (SDNode *I = SelectBitfieldInsert(N))
|
||||
return I;
|
||||
|
||||
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
case ISD::SHL: {
|
||||
@ -988,25 +988,25 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
getI32Imm(SH), getI32Imm(MB), getI32Imm(ME) };
|
||||
return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4);
|
||||
}
|
||||
|
||||
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
case ISD::SRL: {
|
||||
unsigned Imm, SH, MB, ME;
|
||||
if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::AND, Imm) &&
|
||||
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
||||
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
||||
SDValue Ops[] = { N->getOperand(0).getOperand(0),
|
||||
getI32Imm(SH), getI32Imm(MB), getI32Imm(ME) };
|
||||
return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4);
|
||||
}
|
||||
|
||||
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
case ISD::SELECT_CC: {
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
|
||||
|
||||
|
||||
// Handle the setcc cases here. select_cc lhs, 0, 1, 0, cc
|
||||
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
|
||||
if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N->getOperand(2)))
|
||||
@ -1058,7 +1058,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
case ISD::BR_CC: {
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||
SDValue CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC, dl);
|
||||
SDValue Ops[] = { getI32Imm(getPredicateForSetCC(CC)), CondCode,
|
||||
SDValue Ops[] = { getI32Imm(getPredicateForSetCC(CC)), CondCode,
|
||||
N->getOperand(4), N->getOperand(0) };
|
||||
return CurDAG->SelectNodeTo(N, PPC::BCC, MVT::Other, Ops, 4);
|
||||
}
|
||||
@ -1072,13 +1072,13 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
return CurDAG->SelectNodeTo(N, PPC::BCTR, MVT::Other, Chain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return SelectCode(N);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// createPPCISelDag - This pass converts a legalized DAG into a
|
||||
/// createPPCISelDag - This pass converts a legalized DAG into a
|
||||
/// PowerPC-specific DAG, ready for instruction scheduling.
|
||||
///
|
||||
FunctionPass *llvm::createPPCISelDag(PPCTargetMachine &TM) {
|
||||
|
@ -39,7 +39,7 @@ PPCInstrInfo::PPCInstrInfo(PPCTargetMachine &tm)
|
||||
: TargetInstrInfoImpl(PPCInsts, array_lengthof(PPCInsts)), TM(tm),
|
||||
RI(*TM.getSubtargetImpl(), *this) {}
|
||||
|
||||
unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
|
||||
unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
@ -57,7 +57,7 @@ unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
||||
unsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
@ -84,11 +84,11 @@ PPCInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const {
|
||||
// Normal instructions can be commuted the obvious way.
|
||||
if (MI->getOpcode() != PPC::RLWIMI)
|
||||
return TargetInstrInfoImpl::commuteInstruction(MI, NewMI);
|
||||
|
||||
|
||||
// Cannot commute if it has a non-zero rotate count.
|
||||
if (MI->getOperand(3).getImm() != 0)
|
||||
return 0;
|
||||
|
||||
|
||||
// If we have a zero rotate count, we have:
|
||||
// M = mask(MB,ME)
|
||||
// Op0 = (Op1 & ~M) | (Op2 & M)
|
||||
@ -135,14 +135,14 @@ PPCInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const {
|
||||
MI->getOperand(1).setReg(Reg2);
|
||||
MI->getOperand(2).setIsKill(Reg1IsKill);
|
||||
MI->getOperand(1).setIsKill(Reg2IsKill);
|
||||
|
||||
|
||||
// Swap the mask around.
|
||||
MI->getOperand(4).setImm((ME+1) & 31);
|
||||
MI->getOperand(5).setImm((MB-1) & 31);
|
||||
return MI;
|
||||
}
|
||||
|
||||
void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
|
||||
void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const {
|
||||
DebugLoc DL;
|
||||
BuildMI(MBB, MI, DL, get(PPC::NOP));
|
||||
@ -169,7 +169,7 @@ bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
|
||||
// Get the last instruction in the block.
|
||||
MachineInstr *LastInst = I;
|
||||
|
||||
|
||||
// If there is only one terminator instruction, process it.
|
||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
|
||||
if (LastInst->getOpcode() == PPC::B) {
|
||||
@ -189,7 +189,7 @@ bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
// Otherwise, don't know what this is.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Get the instruction before it if it's a terminator.
|
||||
MachineInstr *SecondLastInst = I;
|
||||
|
||||
@ -197,9 +197,9 @@ bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
if (SecondLastInst && I != MBB.begin() &&
|
||||
isUnpredicatedTerminator(--I))
|
||||
return true;
|
||||
|
||||
|
||||
// If the block ends with PPC::B and PPC:BCC, handle it.
|
||||
if (SecondLastInst->getOpcode() == PPC::BCC &&
|
||||
if (SecondLastInst->getOpcode() == PPC::BCC &&
|
||||
LastInst->getOpcode() == PPC::B) {
|
||||
if (!SecondLastInst->getOperand(2).isMBB() ||
|
||||
!LastInst->getOperand(0).isMBB())
|
||||
@ -210,10 +210,10 @@ bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
FBB = LastInst->getOperand(0).getMBB();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// If the block ends with two PPC:Bs, handle it. The second one is not
|
||||
// executed, so remove it.
|
||||
if (SecondLastInst->getOpcode() == PPC::B &&
|
||||
if (SecondLastInst->getOpcode() == PPC::B &&
|
||||
LastInst->getOpcode() == PPC::B) {
|
||||
if (!SecondLastInst->getOperand(0).isMBB())
|
||||
return true;
|
||||
@ -239,17 +239,17 @@ unsigned PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
|
||||
}
|
||||
if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC)
|
||||
return 0;
|
||||
|
||||
|
||||
// Remove the branch.
|
||||
I->eraseFromParent();
|
||||
|
||||
|
||||
I = MBB.end();
|
||||
|
||||
if (I == MBB.begin()) return 1;
|
||||
--I;
|
||||
if (I->getOpcode() != PPC::BCC)
|
||||
return 1;
|
||||
|
||||
|
||||
// Remove the branch.
|
||||
I->eraseFromParent();
|
||||
return 2;
|
||||
@ -262,9 +262,9 @@ PPCInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
||||
DebugLoc DL) const {
|
||||
// Shouldn't be a fall through.
|
||||
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
|
||||
assert((Cond.size() == 2 || Cond.size() == 0) &&
|
||||
assert((Cond.size() == 2 || Cond.size() == 0) &&
|
||||
"PPC branch conditions have two components!");
|
||||
|
||||
|
||||
// One-way branch.
|
||||
if (FBB == 0) {
|
||||
if (Cond.empty()) // Unconditional branch
|
||||
@ -274,7 +274,7 @@ PPCInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
||||
.addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Two-way Conditional Branch.
|
||||
BuildMI(&MBB, DL, get(PPC::BCC))
|
||||
.addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
|
||||
@ -377,11 +377,11 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF,
|
||||
|
||||
// We need to store the CR in the low 4-bits of the saved value. First,
|
||||
// issue a MFCR to save all of the CRBits.
|
||||
unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ?
|
||||
unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ?
|
||||
PPC::R2 : PPC::R0;
|
||||
NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFCRpseud), ScratchReg)
|
||||
.addReg(SrcReg, getKillRegState(isKill)));
|
||||
|
||||
|
||||
// If the saved register wasn't CR0, shift the bits left so that they are
|
||||
// in CR0's slot.
|
||||
if (SrcReg != PPC::CR0) {
|
||||
@ -391,7 +391,7 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF,
|
||||
.addReg(ScratchReg).addImm(ShiftBits)
|
||||
.addImm(0).addImm(31));
|
||||
}
|
||||
|
||||
|
||||
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW))
|
||||
.addReg(ScratchReg,
|
||||
getKillRegState(isKill)),
|
||||
@ -428,14 +428,14 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF,
|
||||
SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN)
|
||||
Reg = PPC::CR7;
|
||||
|
||||
return StoreRegToStackSlot(MF, Reg, isKill, FrameIdx,
|
||||
return StoreRegToStackSlot(MF, Reg, isKill, FrameIdx,
|
||||
PPC::CRRCRegisterClass, NewMIs);
|
||||
|
||||
} else if (RC == PPC::VRRCRegisterClass) {
|
||||
// We don't have indexed addressing for vector loads. Emit:
|
||||
// R0 = ADDI FI#
|
||||
// STVX VAL, 0, R0
|
||||
//
|
||||
//
|
||||
// FIXME: We use R0 here, because it isn't available for RA.
|
||||
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::ADDI), PPC::R0),
|
||||
FrameIdx, 0, 0));
|
||||
@ -514,9 +514,9 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
||||
// at the moment.
|
||||
unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ?
|
||||
PPC::R2 : PPC::R0;
|
||||
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ),
|
||||
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ),
|
||||
ScratchReg), FrameIdx));
|
||||
|
||||
|
||||
// If the reloaded register isn't CR0, shift the bits right so that they are
|
||||
// in the right CR's slot.
|
||||
if (DestReg != PPC::CR0) {
|
||||
@ -526,11 +526,11 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
||||
.addReg(ScratchReg).addImm(32-ShiftBits).addImm(0)
|
||||
.addImm(31));
|
||||
}
|
||||
|
||||
|
||||
NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg)
|
||||
.addReg(ScratchReg));
|
||||
} else if (RC == PPC::CRBITRCRegisterClass) {
|
||||
|
||||
|
||||
unsigned Reg = 0;
|
||||
if (DestReg == PPC::CR0LT || DestReg == PPC::CR0GT ||
|
||||
DestReg == PPC::CR0EQ || DestReg == PPC::CR0UN)
|
||||
@ -557,14 +557,14 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
||||
DestReg == PPC::CR7EQ || DestReg == PPC::CR7UN)
|
||||
Reg = PPC::CR7;
|
||||
|
||||
return LoadRegFromStackSlot(MF, DL, Reg, FrameIdx,
|
||||
return LoadRegFromStackSlot(MF, DL, Reg, FrameIdx,
|
||||
PPC::CRRCRegisterClass, NewMIs);
|
||||
|
||||
} else if (RC == PPC::VRRCRegisterClass) {
|
||||
// We don't have indexed addressing for vector loads. Emit:
|
||||
// R0 = ADDI FI#
|
||||
// Dest = LVX 0, R0
|
||||
//
|
||||
//
|
||||
// FIXME: We use R0 here, because it isn't available for RA.
|
||||
NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::ADDI), PPC::R0),
|
||||
FrameIdx, 0, 0));
|
||||
|
@ -32,7 +32,7 @@ enum {
|
||||
/// PPC970_First - This instruction starts a new dispatch group, so it will
|
||||
/// always be the first one in the group.
|
||||
PPC970_First = 0x1,
|
||||
|
||||
|
||||
/// PPC970_Single - This instruction starts a new dispatch group and
|
||||
/// terminates it, so it will be the sole instruction in the group.
|
||||
PPC970_Single = 0x2,
|
||||
@ -40,7 +40,7 @@ enum {
|
||||
/// PPC970_Cracked - This instruction is cracked into two pieces, requiring
|
||||
/// two dispatch pipes to be available to issue.
|
||||
PPC970_Cracked = 0x4,
|
||||
|
||||
|
||||
/// PPC970_Mask/Shift - This is a bitmask that selects the pipeline type that
|
||||
/// an instruction is issued to.
|
||||
PPC970_Shift = 3,
|
||||
@ -59,8 +59,8 @@ enum PPC970_Unit {
|
||||
PPC970_BRU = 7 << PPC970_Shift // Branch Unit
|
||||
};
|
||||
} // end namespace PPCII
|
||||
|
||||
|
||||
|
||||
|
||||
class PPCInstrInfo : public TargetInstrInfoImpl {
|
||||
PPCTargetMachine &TM;
|
||||
const PPCRegisterInfo RI;
|
||||
@ -69,7 +69,7 @@ class PPCInstrInfo : public TargetInstrInfoImpl {
|
||||
unsigned SrcReg, bool isKill, int FrameIdx,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
||||
void LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
||||
void LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
|
||||
unsigned DestReg, int FrameIdx,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
||||
@ -90,8 +90,8 @@ public:
|
||||
// commuteInstruction - We can commute rlwimi instructions, but only if the
|
||||
// rotate amt is zero. We also have to munge the immediates a bit.
|
||||
virtual MachineInstr *commuteInstruction(MachineInstr *MI, bool NewMI) const;
|
||||
|
||||
virtual void insertNoop(MachineBasicBlock &MBB,
|
||||
|
||||
virtual void insertNoop(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const;
|
||||
|
||||
|
||||
@ -109,7 +109,7 @@ public:
|
||||
MachineBasicBlock::iterator I, DebugLoc DL,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc) const;
|
||||
|
||||
|
||||
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI,
|
||||
unsigned SrcReg, bool isKill, int FrameIndex,
|
||||
@ -121,7 +121,7 @@ public:
|
||||
unsigned DestReg, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
|
||||
|
||||
virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
|
||||
int FrameIx,
|
||||
uint64_t Offset,
|
||||
@ -130,7 +130,7 @@ public:
|
||||
|
||||
virtual
|
||||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
|
||||
|
||||
|
||||
/// GetInstSize - Return the number of bytes of code the specified
|
||||
/// instruction may be. This returns the maximum number of bytes.
|
||||
///
|
||||
|
@ -128,7 +128,7 @@ bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData,
|
||||
|
||||
/// insertNoop - Insert a noop into the instruction stream at the specified
|
||||
/// point.
|
||||
void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
|
||||
void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const {
|
||||
llvm_unreachable("Target didn't implement insertNoop!");
|
||||
}
|
||||
@ -137,7 +137,7 @@ void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
|
||||
bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
|
||||
const TargetInstrDesc &TID = MI->getDesc();
|
||||
if (!TID.isTerminator()) return false;
|
||||
|
||||
|
||||
// Conditional branch is a special case.
|
||||
if (TID.isBranch() && !TID.isBarrier())
|
||||
return true;
|
||||
@ -157,8 +157,8 @@ bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
|
||||
/// may be overloaded in the target code to do that.
|
||||
unsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
|
||||
const MCAsmInfo &MAI) const {
|
||||
|
||||
|
||||
|
||||
|
||||
// Count the number of instructions in the asm.
|
||||
bool atInsnStart = true;
|
||||
unsigned Length = 0;
|
||||
@ -173,6 +173,6 @@ unsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
|
||||
strlen(MAI.getCommentString())) == 0)
|
||||
atInsnStart = false;
|
||||
}
|
||||
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user