[llvm-commits] [llvm] r166122 - in /llvm/trunk: include/llvm/CodeGen/SchedulerRegistry.h lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h

Jim Grosbach grosbach at apple.com
Wed Oct 17 14:52:48 PDT 2012


Any reasonable way to get some test cases?

-Jim

On Oct 17, 2012, at 12:39 PM, Evan Cheng <evan.cheng at apple.com> wrote:

> Author: evancheng
> Date: Wed Oct 17 14:39:36 2012
> New Revision: 166122
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=166122&view=rev
> Log:
> Add a really faster pre-RA scheduler (-pre-RA-sched=linearize). It doesn't use
> any scheduling heuristics nor does it build up any scheduling data structure
> that other heuristics use. It essentially linearize by doing a DFA walk but
> it does handle glues correctly.
> 
> IMPORTANT: it probably can't handle all the physical register dependencies so
> it's not suitable for x86. It also doesn't deal with dbg_value nodes right now
> so it's definitely is still WIP.
> 
> rdar://12474515
> 
> Modified:
>    llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h
>    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
>    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
>    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
> 
> Modified: llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h?rev=166122&r1=166121&r2=166122&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/SchedulerRegistry.h Wed Oct 17 14:39:36 2012
> @@ -102,6 +102,11 @@
> ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS,
>                                            CodeGenOpt::Level OptLevel);
> 
> +/// createDAGLinearizer - This creates a "no-scheduling" scheduler which
> +/// linearize the DAG using topological order.
> +ScheduleDAGSDNodes *createDAGLinearizer(SelectionDAGISel *IS,
> +                                        CodeGenOpt::Level OptLevel);
> +
> } // end namespace llvm
> 
> #endif
> 
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp?rev=166122&r1=166121&r2=166122&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp Wed Oct 17 14:39:36 2012
> @@ -13,6 +13,7 @@
> 
> #define DEBUG_TYPE "pre-RA-sched"
> #include "ScheduleDAGSDNodes.h"
> +#include "InstrEmitter.h"
> #include "llvm/InlineAsm.h"
> #include "llvm/CodeGen/SchedulerRegistry.h"
> #include "llvm/CodeGen/SelectionDAGISel.h"
> @@ -34,6 +35,10 @@
> static RegisterScheduler
>   fastDAGScheduler("fast", "Fast suboptimal list scheduling",
>                    createFastDAGScheduler);
> +static RegisterScheduler
> +  linearizeDAGScheduler("linearize", "Linearize DAG, no scheduling",
> +                        createDAGLinearizer);
> +
> 
> namespace {
>   /// FastPriorityQueue - A degenerate priority queue that considers
> @@ -629,6 +634,153 @@
> #endif
> }
> 
> +
> +//===----------------------------------------------------------------------===//
> +// ScheduleDAGLinearize - No scheduling scheduler, it simply linearize the
> +// DAG in topological order.
> +// IMPORTANT: this may not work for targets with phyreg dependency.
> +//
> +class ScheduleDAGLinearize : public ScheduleDAGSDNodes {
> +public:
> +  ScheduleDAGLinearize(MachineFunction &mf) : ScheduleDAGSDNodes(mf) {}
> +
> +  void Schedule();
> +
> +  MachineBasicBlock *EmitSchedule(MachineBasicBlock::iterator &InsertPos);
> +
> +private:
> +  std::vector<SDNode*> Sequence;
> +  DenseMap<SDNode*, SDNode*> GluedMap;  // Cache glue to its user
> +
> +  void ScheduleNode(SDNode *N);
> +};
> +
> +void ScheduleDAGLinearize::ScheduleNode(SDNode *N) {
> +  if (N->getNodeId() != 0)
> +    llvm_unreachable(0);
> +
> +  if (!N->isMachineOpcode() &&
> +      (N->getOpcode() == ISD::EntryToken || isPassiveNode(N)))
> +    // These nodes do not need to be translated into MIs.
> +    return;
> +
> +  DEBUG(dbgs() << "\n*** Scheduling: ");
> +  DEBUG(N->dump(DAG));
> +  Sequence.push_back(N);
> +
> +  unsigned NumOps = N->getNumOperands();
> +  if (unsigned NumLeft = NumOps) {
> +    SDNode *GluedOpN = 0;
> +    do {
> +      const SDValue &Op = N->getOperand(NumLeft-1);
> +      SDNode *OpN = Op.getNode();
> +
> +      if (NumLeft == NumOps && Op.getValueType() == MVT::Glue) {
> +        // Schedule glue operand right above N.
> +        GluedOpN = OpN;
> +        assert(OpN->getNodeId() != 0 && "Glue operand not ready?");
> +        OpN->setNodeId(0);
> +        ScheduleNode(OpN);
> +        continue;
> +      }
> +
> +      if (OpN == GluedOpN)
> +        // Glue operand is already scheduled.
> +        continue;
> +
> +      DenseMap<SDNode*, SDNode*>::iterator DI = GluedMap.find(OpN);
> +      if (DI != GluedMap.end() && DI->second != N)
> +        // Users of glues are counted against the glued users.
> +        OpN = DI->second;
> +
> +      unsigned Degree = OpN->getNodeId();
> +      assert(Degree > 0 && "Predecessor over-released!");
> +      OpN->setNodeId(--Degree);
> +      if (Degree == 0)
> +        ScheduleNode(OpN);
> +    } while (--NumLeft);
> +  }
> +}
> +
> +/// findGluedUser - Find the representative use of a glue value by walking
> +/// the use chain.
> +static SDNode *findGluedUser(SDNode *N) {
> +  while (SDNode *Glued = N->getGluedUser())
> +    N = Glued;
> +  return N;
> +}
> +
> +void ScheduleDAGLinearize::Schedule() {
> +  DEBUG(dbgs() << "********** DAG Linearization **********\n");
> +
> +  SmallVector<SDNode*, 8> Glues;
> +  unsigned DAGSize = 0;
> +  for (SelectionDAG::allnodes_iterator I = DAG->allnodes_begin(),
> +         E = DAG->allnodes_end(); I != E; ++I) {
> +    SDNode *N = I;
> +
> +    // Use node id to record degree.
> +    unsigned Degree = N->use_size();
> +    N->setNodeId(Degree);
> +    unsigned NumVals = N->getNumValues();
> +    if (NumVals && N->getValueType(NumVals-1) == MVT::Glue &&
> +        N->hasAnyUseOfValue(NumVals-1)) {
> +      SDNode *User = findGluedUser(N);
> +      if (User) {
> +        Glues.push_back(N);
> +        GluedMap.insert(std::make_pair(N, User));
> +      }
> +    }
> +
> +    if (N->isMachineOpcode() ||
> +        (N->getOpcode() != ISD::EntryToken && !isPassiveNode(N)))
> +      ++DAGSize;
> +  }
> +
> +  for (unsigned i = 0, e = Glues.size(); i != e; ++i) {
> +    SDNode *Glue = Glues[i];
> +    SDNode *GUser = GluedMap[Glue];
> +    unsigned Degree = Glue->getNodeId();
> +    unsigned UDegree = GUser->getNodeId();
> +
> +    // Glue user must be scheduled together with the glue operand. So other
> +    // users of the glue operand must be treated as its users.
> +    SDNode *ImmGUser = Glue->getGluedUser();
> +    for (SDNode::use_iterator ui = Glue->use_begin(), ue = Glue->use_end();
> +         ui != ue; ++ui)
> +      if (*ui == ImmGUser)
> +        --Degree;
> +    GUser->setNodeId(UDegree + Degree);
> +    Glue->setNodeId(1);
> +  }
> +
> +  Sequence.reserve(DAGSize);
> +  ScheduleNode(DAG->getRoot().getNode());
> +}
> +
> +MachineBasicBlock*
> +ScheduleDAGLinearize::EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
> +  InstrEmitter Emitter(BB, InsertPos);
> +  DenseMap<SDValue, unsigned> VRBaseMap;
> +
> +  DEBUG({
> +      dbgs() << "\n*** Final schedule ***\n";
> +    });
> +
> +  // FIXME: Handle dbg_values.
> +  unsigned NumNodes = Sequence.size();
> +  for (unsigned i = 0; i != NumNodes; ++i) {
> +    SDNode *N = Sequence[NumNodes-i-1];
> +    DEBUG(N->dump(DAG));
> +    Emitter.EmitNode(N, false, false, VRBaseMap);
> +  }
> +
> +  DEBUG(dbgs() << '\n');
> +
> +  InsertPos = Emitter.getInsertPos();
> +  return Emitter.getBlock();
> +}
> +
> //===----------------------------------------------------------------------===//
> //                         Public Constructor Functions
> //===----------------------------------------------------------------------===//
> @@ -637,3 +789,8 @@
> llvm::createFastDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) {
>   return new ScheduleDAGFast(*IS->MF);
> }
> +
> +llvm::ScheduleDAGSDNodes *
> +llvm::createDAGLinearizer(SelectionDAGISel *IS, CodeGenOpt::Level) {
> +  return new ScheduleDAGLinearize(*IS->MF);
> +}
> 
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=166122&r1=166121&r2=166122&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Wed Oct 17 14:39:36 2012
> @@ -831,8 +831,7 @@
>     }
> 
>     SmallVector<SDNode *, 4> GluedNodes;
> -    for (SDNode *N = SU->getNode()->getGluedNode(); N;
> -         N = N->getGluedNode())
> +    for (SDNode *N = SU->getNode()->getGluedNode(); N; N = N->getGluedNode())
>       GluedNodes.push_back(N);
>     while (!GluedNodes.empty()) {
>       SDNode *N = GluedNodes.back();
> 
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h?rev=166122&r1=166121&r2=166122&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h Wed Oct 17 14:39:36 2012
> @@ -114,7 +114,8 @@
>     /// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock
>     /// according to the order specified in Sequence.
>     ///
> -    MachineBasicBlock *EmitSchedule(MachineBasicBlock::iterator &InsertPos);
> +    virtual MachineBasicBlock*
> +    EmitSchedule(MachineBasicBlock::iterator &InsertPos);
> 
>     virtual void dumpNode(const SUnit *SU) const;
> 
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list