[llvm] r217504 - [AArch64] Add experimental PBQP support
Chad Rosier
mcrosier at codeaurora.org
Wed Sep 10 10:16:31 PDT 2014
No problem, Arnaud. Very cool work!
> 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