[llvm] r217504 - [AArch64] Add experimental PBQP support

Arnaud A. de Grandmaison arnaud.degrandmaison at arm.com
Wed Sep 10 10:14:49 PDT 2014


Hi Chad,

I have addressed all your comments with r217518.

Thanks for the review !
--
Arnaud

-----Original Message-----
From: Chad Rosier [mailto:mcrosier at codeaurora.org] 
Sent: 10 September 2014 15:59
To: Arnaud De Grandmaison
Cc: llvm-commits at cs.uiuc.edu
Subject: Re: [llvm] r217504 - [AArch64] Add experimental PBQP support

> Author: aadg
> Date: Wed Sep 10 09:06:10 2014
> New Revision: 217504
>
> URL: http://llvm.org/viewvc/llvm-project?rev=217504&view=rev
> Log:
> [AArch64] Add experimental PBQP support
>
> This adds target specific support for using the PBQP register 
> allocator on the AArch64, for the A57 cpu.
>
> By default, the PBQP allocator is not used, unless explicitely 
> required on the command line with "-aarch64-pbqp".
>
> Added:
>     llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp
>     llvm/trunk/test/CodeGen/AArch64/PBQP.ll
> Modified:
>     llvm/trunk/lib/Target/AArch64/AArch64.h
>     llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp
>     llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.h
>     llvm/trunk/lib/Target/AArch64/CMakeLists.txt
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArc
> h64.h?rev=217504&r1=217503&r2=217504&view=diff
> ======================================================================
> ========
> --- llvm/trunk/lib/Target/AArch64/AArch64.h (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64.h Wed Sep 10 09:06:10 2014
> @@ -39,6 +39,7 @@ ModulePass *createAArch64PromoteConstant  
> FunctionPass *createAArch64ConditionOptimizerPass();
>  FunctionPass *createAArch64AddressTypePromotionPass();
>  FunctionPass *createAArch64A57FPLoadBalancing();
> +FunctionPass *createAArch64A57PBQPRegAlloc();
>  /// \brief Creates an ARM-specific Target Transformation Info pass.
>  ImmutablePass *
>  createAArch64TargetTransformInfoPass(const AArch64TargetMachine *TM);
>
> Added: llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArc
> h64PBQPRegAlloc.cpp?rev=217504&view=auto
> ======================================================================
> ========
> --- llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp (added)
> +++ llvm/trunk/lib/Target/AArch64/AArch64PBQPRegAlloc.cpp Wed Sep 10
> 09:06:10 2014
> @@ -0,0 +1,413 @@
> +//===-- AArch64PBQPRegAlloc.cpp - AArch64 specific PBQP constraints
> -------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open 
> +Source // License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------
> +------===// // This file contains the AArch64 / Cortex-A57 specific 
> +register
> allocation
> +// constraints for use by the PBQP register allocator.
> +//
> +// It is essentially a transcription of what is contained in // 
> +AArch64A57FPLoadBalancing, which tries to use a balanced // mix of 
> +odd and even D-registers when performing a critical sequence of // 
> +independent, non-quadword FP/ASIMD floating-point
> multiply-accumulates.
> +//===----------------------------------------------------------------
> +------===//
> +
> +#define DEBUG_TYPE "aarch64-pbqp"
> +
> +#include "AArch64.h"
> +#include "AArch64RegisterInfo.h"
> +
> +#include "llvm/ADT/SetVector.h"
> +#include "llvm/CodeGen/LiveIntervalAnalysis.h"
> +#include "llvm/CodeGen/MachineBasicBlock.h"
> +#include "llvm/CodeGen/MachineFunction.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/CodeGen/RegAllocPBQP.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/ErrorHandling.h"
> +#include "llvm/Support/raw_ostream.h"
> +
> +#define PBQP_BUILDER PBQPBuilderWithCoalescing //#define PBQP_BUILDER 
> +PBQPBuilder

Please remove commented out #define.

> +
> +using namespace llvm;
> +
> +namespace {
> +
> +bool isFPReg(unsigned reg) {
> +  return AArch64::FPR32RegClass.contains(reg) ||
> +         AArch64::FPR64RegClass.contains(reg) ||
> +         AArch64::FPR128RegClass.contains(reg);
> +};
> +
> +bool isOdd(unsigned reg) {
> +  switch (reg) {
> +  default:
> +    llvm_unreachable("Register is not from the expected class !");
> +  case AArch64::S1:
> +  case AArch64::S3:
> +  case AArch64::S5:
> +  case AArch64::S7:
> +  case AArch64::S9:
> +  case AArch64::S11:
> +  case AArch64::S13:
> +  case AArch64::S15:
> +  case AArch64::S17:
> +  case AArch64::S19:
> +  case AArch64::S21:
> +  case AArch64::S23:
> +  case AArch64::S25:
> +  case AArch64::S27:
> +  case AArch64::S29:
> +  case AArch64::S31:
> +  case AArch64::D1:
> +  case AArch64::D3:
> +  case AArch64::D5:
> +  case AArch64::D7:
> +  case AArch64::D9:
> +  case AArch64::D11:
> +  case AArch64::D13:
> +  case AArch64::D15:
> +  case AArch64::D17:
> +  case AArch64::D19:
> +  case AArch64::D21:
> +  case AArch64::D23:
> +  case AArch64::D25:
> +  case AArch64::D27:
> +  case AArch64::D29:
> +  case AArch64::D31:
> +  case AArch64::Q1:
> +  case AArch64::Q3:
> +  case AArch64::Q5:
> +  case AArch64::Q7:
> +  case AArch64::Q9:
> +  case AArch64::Q11:
> +  case AArch64::Q13:
> +  case AArch64::Q15:
> +  case AArch64::Q17:
> +  case AArch64::Q19:
> +  case AArch64::Q21:
> +  case AArch64::Q23:
> +  case AArch64::Q25:
> +  case AArch64::Q27:
> +  case AArch64::Q29:
> +  case AArch64::Q31:
> +    return true;
> +  case AArch64::S0:
> +  case AArch64::S2:
> +  case AArch64::S4:
> +  case AArch64::S6:
> +  case AArch64::S8:
> +  case AArch64::S10:
> +  case AArch64::S12:
> +  case AArch64::S14:
> +  case AArch64::S16:
> +  case AArch64::S18:
> +  case AArch64::S20:
> +  case AArch64::S22:
> +  case AArch64::S24:
> +  case AArch64::S26:
> +  case AArch64::S28:
> +  case AArch64::S30:
> +  case AArch64::D0:
> +  case AArch64::D2:
> +  case AArch64::D4:
> +  case AArch64::D6:
> +  case AArch64::D8:
> +  case AArch64::D10:
> +  case AArch64::D12:
> +  case AArch64::D14:
> +  case AArch64::D16:
> +  case AArch64::D18:
> +  case AArch64::D20:
> +  case AArch64::D22:
> +  case AArch64::D24:
> +  case AArch64::D26:
> +  case AArch64::D28:
> +  case AArch64::D30:
> +  case AArch64::Q0:
> +  case AArch64::Q2:
> +  case AArch64::Q4:
> +  case AArch64::Q6:
> +  case AArch64::Q8:
> +  case AArch64::Q10:
> +  case AArch64::Q12:
> +  case AArch64::Q14:
> +  case AArch64::Q16:
> +  case AArch64::Q18:
> +  case AArch64::Q20:
> +  case AArch64::Q22:
> +  case AArch64::Q24:
> +  case AArch64::Q26:
> +  case AArch64::Q28:
> +  case AArch64::Q30:
> +    return false;
> +
> +  }
> +}
> +
> +bool haveSameParity(unsigned reg1, unsigned reg2) {
> +  assert(isFPReg(reg1) && "Expecting an FP register for reg1");
> +  assert(isFPReg(reg2) && "Expecting an FP register for reg2");
> +
> +  return isOdd(reg1) == isOdd(reg2);
> +}
> +
> +class A57PBQPBuilder : public PBQP_BUILDER {
> +public:
> +  A57PBQPBuilder() : PBQP_BUILDER(), TRI(nullptr), LIs(nullptr), 
> +Chains()
> {}
> +
> +  // Build a PBQP instance to represent the register allocation 
> + problem
> for
> +  // the given MachineFunction.
> +  std::unique_ptr<PBQPRAProblem>
> +  build(MachineFunction *MF, const LiveIntervals *LI,
> +        const MachineBlockFrequencyInfo *blockInfo,
> +        const RegSet &VRegs) override;
> +
> +private:
> +  const AArch64RegisterInfo *TRI;
> +  const LiveIntervals *LIs;
> +  SmallSetVector<unsigned, 32> Chains;
> +
> +  // Return true if reg is a physical register  bool 
> + isPhysicalReg(unsigned reg) const {
> +    return TRI->isPhysicalRegister(reg);  }
> +
> +  // Add the accumulator chaining constraint, inside the chain, i.e. 
> + so
> that
> +  // parity(Rd) == parity(Ra).
> +  // \return true if a constraint was added  bool 
> + addIntraChainConstraint(PBQPRAProblem *p, unsigned Rd, unsigned
> Ra);
> +
> +  // Add constraints between existing chains  void 
> + addInterChainConstraint(PBQPRAProblem *p, unsigned Rd, unsigned
> Ra);
> +};
> +} // Anonymous namespace
> +
> +bool A57PBQPBuilder::addIntraChainConstraint(PBQPRAProblem *p, 
> +unsigned
> Rd,
> +                                             unsigned Ra) {  if (Rd 
> + == Ra)
> +    return false;
> +
> +  if (isPhysicalReg(Rd) || isPhysicalReg(Ra)) {
> +    dbgs() << "Rd is a physical reg:" << isPhysicalReg(Rd) << '\n';
> +    dbgs() << "Ra is a physical reg:" << isPhysicalReg(Ra) << '\n';

Please use the DEBUG() macro on these debug statements.
http://llvm.org/docs/ProgrammersManual.html#the-debug-macro-and-debug-option

> +    return false;
> +  }
> +
> +  const PBQPRAProblem::AllowedSet *vRdAllowed = 
> + &p->getAllowedSet(Rd);  const PBQPRAProblem::AllowedSet *vRaAllowed 
> + = &p->getAllowedSet(Ra);
> +
> +  PBQPRAGraph &g = p->getGraph();
> +  PBQPRAGraph::NodeId node1 = p->getNodeForVReg(Rd);  
> + PBQPRAGraph::NodeId node2 = p->getNodeForVReg(Ra);  
> + PBQPRAGraph::EdgeId edge = g.findEdge(node1, node2);
> +
> +  // The edge does not exist. Create one with the appropriate
> interference
> +  // costs.
> +  if (edge == g.invalidEdgeId()) {
> +    const LiveInterval &ld = LIs->getInterval(Rd);
> +    const LiveInterval &la = LIs->getInterval(Ra);
> +    bool livesOverlap = ld.overlaps(la);
> +
> +    PBQP::Matrix costs(vRdAllowed->size() + 1, vRaAllowed->size() + 
> + 1,
> 0);
> +    for (unsigned i = 0; i != vRdAllowed->size(); ++i) {

Assuming vRdAllowed->size() is loop invariant, please use the canonical
form:

    for (unsigned i = 0, e = vRdAllowed->size(); i != e; ++i) {


> +      unsigned pRd = (*vRdAllowed)[i];
> +      for (unsigned j = 0; j != vRaAllowed->size(); ++j) {

Same.

> +        unsigned pRa = (*vRaAllowed)[j];
> +        if (livesOverlap && TRI->regsOverlap(pRd, pRa))
> +          costs[i + 1][j + 1] =
> std::numeric_limits<PBQP::PBQPNum>::infinity();
> +        else
> +          costs[i + 1][j + 1] = haveSameParity(pRd, pRa) ? 0.0 : 1.0;
> +      }
> +    }
> +    g.addEdge(node1, node2, std::move(costs));
> +    return true;
> +  }
> +
> +  if (g.getEdgeNode1Id(edge) == node2) {
> +    std::swap(node1, node2);
> +    std::swap(vRdAllowed, vRaAllowed);  }
> +
> +  // Enforce minCost(sameParity(RaClass)) > 
> + maxCost(otherParity(RdClass))  PBQP::Matrix 
> + costs(g.getEdgeCosts(edge));  for (unsigned i = 0; i != 
> + vRdAllowed->size(); ++i) {

Same.

> +    unsigned pRd = (*vRdAllowed)[i];
> +
> +    // Get the maximum cost (excluding unallocatable reg) for same parity
> +    // registers
> +    PBQP::PBQPNum sameParityMax =
> std::numeric_limits<PBQP::PBQPNum>::min();
> +    for (unsigned j = 0; j != vRaAllowed->size(); ++j) {

Same.

> +      unsigned pRa = (*vRaAllowed)[j];
> +      if (haveSameParity(pRd, pRa))
> +        if (costs[i + 1][j + 1] !=
> +                std::numeric_limits<PBQP::PBQPNum>::infinity() &&
> +            costs[i + 1][j + 1] > sameParityMax)
> +          sameParityMax = costs[i + 1][j + 1];
> +    }
> +
> +    // Ensure all registers with a different parity have a higher cost
> +    // than sameParityMax
> +    for (unsigned j = 0; j != vRaAllowed->size(); ++j) {

Same.

> +      unsigned pRa = (*vRaAllowed)[j];
> +      if (!haveSameParity(pRd, pRa))
> +        if (sameParityMax > costs[i + 1][j + 1])
> +          costs[i + 1][j + 1] = sameParityMax + 1.0;
> +    }
> +  }
> +  g.setEdgeCosts(edge, costs);
> +
> +  return true;
> +}
> +
> +void
> +A57PBQPBuilder::addInterChainConstraint(PBQPRAProblem *p, unsigned Rd,
> +                                        unsigned Ra) {
> +  // Do some Chain management
> +  if (Chains.count(Ra)) {
> +    if (Rd != Ra) {
> +      DEBUG(dbgs() << "Moving acc chain from " << PrintReg(Ra, TRI) << "
> to "
> +                   << PrintReg(Rd, TRI) << '\n';);
> +      Chains.remove(Ra);
> +      Chains.insert(Rd);
> +    }
> +  } else {
> +    DEBUG(dbgs() << "Creating new acc chain for " << PrintReg(Rd, TRI)
> +                 << '\n';);
> +    Chains.insert(Rd);
> +  }
> +
> +  const LiveInterval &ld = LIs->getInterval(Rd);  for (auto r : 
> + Chains) {
> +    // Skip self
> +    if (r == Rd)
> +      continue;
> +
> +    const LiveInterval &lr = LIs->getInterval(r);
> +    if (ld.overlaps(lr)) {
> +      const PBQPRAProblem::AllowedSet *vRdAllowed =
> &p->getAllowedSet(Rd);
> +      const PBQPRAProblem::AllowedSet *vRrAllowed = 
> + &p->getAllowedSet(r);
> +
> +      PBQPRAGraph &g = p->getGraph();
> +      PBQPRAGraph::NodeId node1 = p->getNodeForVReg(Rd);
> +      PBQPRAGraph::NodeId node2 = p->getNodeForVReg(r);
> +      PBQPRAGraph::EdgeId edge = g.findEdge(node1, node2);
> +      assert(edge != g.invalidEdgeId() &&
> +             "PBQP error ! The edge should exist !");
> +
> +      DEBUG(dbgs() << "Refining constraint !\n";);
> +
> +      if (g.getEdgeNode1Id(edge) == node2) {
> +        std::swap(node1, node2);
> +        std::swap(vRdAllowed, vRrAllowed);
> +      }
> +
> +      // Enforce that cost is higher with all other Chains of the 
> + same
> parity
> +      PBQP::Matrix costs(g.getEdgeCosts(edge));
> +      for (unsigned i = 0; i != vRdAllowed->size(); ++i) {
> +        unsigned pRd = (*vRdAllowed)[i];
> +
> +        // Get the maximum cost (excluding unallocatable reg) for all
> other
> +        // parity registers
> +        PBQP::PBQPNum sameParityMax =
> std::numeric_limits<PBQP::PBQPNum>::min();
> +        for (unsigned j = 0; j != vRrAllowed->size(); ++j) {

Same.

> +          unsigned pRa = (*vRrAllowed)[j];
> +          if (!haveSameParity(pRd, pRa))
> +            if (costs[i + 1][j + 1] !=
> +                    std::numeric_limits<PBQP::PBQPNum>::infinity() &&
> +                costs[i + 1][j + 1] > sameParityMax)
> +              sameParityMax = costs[i + 1][j + 1];
> +        }
> +
> +        // Ensure all registers with same parity have a higher cost
> +        // than sameParityMax
> +        for (unsigned j = 0; j != vRrAllowed->size(); ++j) {

Same.

> +          unsigned pRa = (*vRrAllowed)[j];
> +          if (haveSameParity(pRd, pRa))
> +            if (sameParityMax > costs[i + 1][j + 1])
> +              costs[i + 1][j + 1] = sameParityMax + 1.0;
> +        }
> +      }
> +      g.setEdgeCosts(edge, costs);
> +    }
> +  }
> +}
> +
> +std::unique_ptr<PBQPRAProblem>
> +A57PBQPBuilder::build(MachineFunction *MF, const LiveIntervals *LI,
> +                      const MachineBlockFrequencyInfo *blockInfo,
> +                      const RegSet &VRegs) {
> +  std::unique_ptr<PBQPRAProblem> p =
> +      PBQP_BUILDER::build(MF, LI, blockInfo, VRegs);
> +
> +  TRI = static_cast<const AArch64RegisterInfo *>(
> +      MF->getTarget().getSubtargetImpl()->getRegisterInfo());
> +  LIs = LI;
> +
> +  DEBUG(MF->dump(););
> +
> +  for (MachineFunction::const_iterator mbbItr = MF->begin(), mbbEnd =
> MF->end();
> +       mbbItr != mbbEnd; ++mbbItr) {
> +    const MachineBasicBlock *MBB = &*mbbItr;
> +    Chains.clear(); // FIXME: really needed ? Could not work at MF 
> + level
> ?
> +
> +    for (MachineBasicBlock::const_iterator miItr = MBB->begin(),
> +                                           miEnd = MBB->end();
> +         miItr != miEnd; ++miItr) {
> +      const MachineInstr *MI = &*miItr;
> +      switch (MI->getOpcode()) {
> +      case AArch64::FMSUBSrrr:
> +      case AArch64::FMADDSrrr:
> +      case AArch64::FNMSUBSrrr:
> +      case AArch64::FNMADDSrrr:
> +      case AArch64::FMSUBDrrr:
> +      case AArch64::FMADDDrrr:
> +      case AArch64::FNMSUBDrrr:
> +      case AArch64::FNMADDDrrr: {
> +        unsigned Rd = MI->getOperand(0).getReg();
> +        unsigned Ra = MI->getOperand(3).getReg();
> +
> +        if (addIntraChainConstraint(p.get(), Rd, Ra))
> +          addInterChainConstraint(p.get(), Rd, Ra);
> +        break;
> +      }
> +
> +      case AArch64::FMLAv2f32:
> +      case AArch64::FMLSv2f32: {
> +        unsigned Rd = MI->getOperand(0).getReg();
> +        addInterChainConstraint(p.get(), Rd, Rd);
> +        break;
> +      }
> +
> +      default:
> +        // Forget Chains which have been killed
> +        for (auto r : Chains) {
> +          SmallVector<unsigned, 8> toDel;
> +          if (MI->killsRegister(r)) {
> +            DEBUG(dbgs() << "Killing chain " << PrintReg(r, TRI) << " 
> + at
> ";
> +                  MI->print(dbgs()););
> +            toDel.push_back(r);
> +          }
> +
> +          while (!toDel.empty()) {
> +            Chains.remove(toDel.back());
> +            toDel.pop_back();
> +          }
> +        }
> +      }
> +    }
> +  }
> +
> +  return p;
> +}
> +
> +// Factory function used by AArch64TargetMachine to add the pass to 
> +the // passmanager.
> +FunctionPass *llvm::createAArch64A57PBQPRegAlloc() {
> +  std::unique_ptr<PBQP_BUILDER> builder =
> llvm::make_unique<A57PBQPBuilder>();
> +  return createPBQPRegisterAllocator(std::move(builder), nullptr); }
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArc
> h64TargetMachine.cpp?rev=217504&r1=217503&r2=217504&view=diff
> ======================================================================
> ========
> --- llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.cpp Wed Sep 10
> 09:06:10 2014
> @@ -13,6 +13,7 @@
>  #include "AArch64.h"
>  #include "AArch64TargetMachine.h"
>  #include "llvm/CodeGen/Passes.h"
> +#include "llvm/CodeGen/RegAllocRegistry.h"
>  #include "llvm/PassManager.h"
>  #include "llvm/Support/CommandLine.h"
>  #include "llvm/Support/TargetRegistry.h"
> @@ -73,6 +74,10 @@ EnableCondOpt("aarch64-condopt",
>                cl::desc("Enable the condition optimizer pass"),
>                cl::init(true), cl::Hidden);
>
> +static cl::opt<bool>
> +EnablePBQP("aarch64-pbqp", cl::Hidden,
> +           cl::desc("Use PBQP register allocator (experimental)"),
> +           cl::init(false));
>
>  extern "C" void LLVMInitializeAArch64Target() {
>    // Register the target.
> @@ -90,8 +95,14 @@ AArch64TargetMachine::AArch64TargetMachi
>                                             CodeGenOpt::Level OL,
>                                             bool LittleEndian)
>      : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
> -      Subtarget(TT, CPU, FS, *this, LittleEndian) {
> +      Subtarget(TT, CPU, FS, *this, LittleEndian),
> +      usingPBQP(false) {
>    initAsmInfo();
> +
> +  if (EnablePBQP && Subtarget.isCortexA57() && OL != CodeGenOpt::None) {
> +    usingPBQP = true;
> +    RegisterRegAlloc::setDefault(createAArch64A57PBQPRegAlloc);
> +  }
>  }
>
>  void AArch64leTargetMachine::anchor() { } @@ -216,7 +227,8 @@ bool 
> AArch64PassConfig::addPostRegAlloc(
>    if (TM->getOptLevel() != CodeGenOpt::None &&
> EnableDeadRegisterElimination)
>      addPass(createAArch64DeadRegisterDefinitions());
>    if (TM->getOptLevel() != CodeGenOpt::None &&
> -      TM->getSubtarget<AArch64Subtarget>().isCortexA57())
> +      TM->getSubtarget<AArch64Subtarget>().isCortexA57() &&
> +      !static_cast<const AArch64TargetMachine *>(TM)->isPBQPUsed())
>      // Improve performance for some FP/SIMD code for A57.
>      addPass(createAArch64A57FPLoadBalancing());
>    return true;
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArc
> h64TargetMachine.h?rev=217504&r1=217503&r2=217504&view=diff
> ======================================================================
> ========
> --- llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.h (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64TargetMachine.h Wed Sep 10
> 09:06:10 2014
> @@ -40,6 +40,12 @@ public:
>
>    /// \brief Register AArch64 analysis passes with a pass manager.
>    void addAnalysisPasses(PassManagerBase &PM) override;
> +
> +  /// \brief Query if the PBQP register allocator is being used  bool 
> + isPBQPUsed() const { return usingPBQP; }
> +
> +private:
> +  bool usingPBQP;
>  };
>
>  // AArch64leTargetMachine - AArch64 little endian target machine.
>
> Modified: llvm/trunk/lib/Target/AArch64/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/CMak
> eLists.txt?rev=217504&r1=217503&r2=217504&view=diff
> ======================================================================
> ========
> --- llvm/trunk/lib/Target/AArch64/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Target/AArch64/CMakeLists.txt Wed Sep 10 09:06:10 
> +++ 2014
> @@ -34,6 +34,7 @@ add_llvm_target(AArch64CodeGen
>    AArch64LoadStoreOptimizer.cpp
>    AArch64MCInstLower.cpp
>    AArch64PromoteConstant.cpp
> +  AArch64PBQPRegAlloc.cpp
>    AArch64RegisterInfo.cpp
>    AArch64SelectionDAGInfo.cpp
>    AArch64StorePairSuppress.cpp
>
> Added: llvm/trunk/test/CodeGen/AArch64/PBQP.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/PB
> QP.ll?rev=217504&view=auto 
> ======================================================================
> ========
> --- llvm/trunk/test/CodeGen/AArch64/PBQP.ll (added)
> +++ llvm/trunk/test/CodeGen/AArch64/PBQP.ll Wed Sep 10 09:06:10 2014
> @@ -0,0 +1,14 @@
> +; RUN: llc -mtriple=aarch64-linux-gnu -mcpu=cortex-a57 -aarch64-pbqp 
> +-o -
> %s | FileCheck %s
> +
> +define i32 @foo(i32 %a) {
> +; CHECK-LABEL: foo:
> +; CHECK: bl bar
> +; CHECK-NEXT: bl baz
> +  %call = call i32 @bar(i32 %a)
> +  %call1 = call i32 @baz(i32 %call)
> +  ret i32 %call1
> +}
> +
> +declare i32 @bar(i32)
> +declare i32 @baz(i32)
> +
>
>
> _______________________________________________
> 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