X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FR600%2FR600EmitClauseMarkers.cpp;h=fdc20302f4a327a2634b865f8673d4ea42a42a81;hb=12af22e8cc217827cf4f118b0f5e4ebbda9925ae;hp=928c0e3ba6df79970ec600240d491fbd885edf60;hpb=de28bdadff78ceea6bb05e23dc3b4cc92fa359ed;p=oota-llvm.git diff --git a/lib/Target/R600/R600EmitClauseMarkers.cpp b/lib/Target/R600/R600EmitClauseMarkers.cpp index 928c0e3ba6d..fdc20302f4a 100644 --- a/lib/Target/R600/R600EmitClauseMarkers.cpp +++ b/lib/Target/R600/R600EmitClauseMarkers.cpp @@ -19,18 +19,22 @@ #include "R600InstrInfo.h" #include "R600MachineFunctionInfo.h" #include "R600RegisterInfo.h" +#include "AMDGPUSubtarget.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" using namespace llvm; +namespace llvm { + void initializeR600EmitClauseMarkersPass(PassRegistry&); +} + namespace { -class R600EmitClauseMarkersPass : public MachineFunctionPass { +class R600EmitClauseMarkers : public MachineFunctionPass { private: - static char ID; const R600InstrInfo *TII; int Address; @@ -47,6 +51,11 @@ private: break; } + // These will be expanded to two ALU instructions in the + // ExpandSpecialInstructions pass. + if (TII->isLDSRetInstr(MI->getOpcode())) + return 2; + if(TII->isVector(*MI) || TII->isCubeOp(MI->getOpcode()) || TII->isReductionOp(MI->getOpcode())) @@ -106,8 +115,13 @@ private: } bool SubstituteKCacheBank(MachineInstr *MI, - std::vector > &CachedConsts) const { + std::vector > &CachedConsts, + bool UpdateInstr = true) const { std::vector > UsedKCache; + + if (!TII->isALUInstr(MI->getOpcode()) && MI->getOpcode() != AMDGPU::DOT_4) + return true; + const SmallVectorImpl > &Consts = TII->getSrcs(MI); assert((TII->isALUInstr(MI->getOpcode()) || @@ -140,6 +154,9 @@ private: return false; } + if (!UpdateInstr) + return true; + for (unsigned i = 0, j = 0, n = Consts.size(); i < n; ++i) { if (Consts[i].first->getReg() != AMDGPU::ALU_CONST) continue; @@ -160,6 +177,52 @@ private: return true; } + bool canClauseLocalKillFitInClause( + unsigned AluInstCount, + std::vector > KCacheBanks, + MachineBasicBlock::iterator Def, + MachineBasicBlock::iterator BBEnd) { + const R600RegisterInfo &TRI = TII->getRegisterInfo(); + for (MachineInstr::const_mop_iterator + MOI = Def->operands_begin(), + MOE = Def->operands_end(); MOI != MOE; ++MOI) { + if (!MOI->isReg() || !MOI->isDef() || + TRI.isPhysRegLiveAcrossClauses(MOI->getReg())) + continue; + + // Def defines a clause local register, so check that its use will fit + // in the clause. + unsigned LastUseCount = 0; + for (MachineBasicBlock::iterator UseI = Def; UseI != BBEnd; ++UseI) { + AluInstCount += OccupiedDwords(UseI); + // Make sure we won't need to end the clause due to KCache limitations. + if (!SubstituteKCacheBank(UseI, KCacheBanks, false)) + return false; + + // We have reached the maximum instruction limit before finding the + // use that kills this register, so we cannot use this def in the + // current clause. + if (AluInstCount >= TII->getMaxAlusPerClause()) + return false; + + // Register kill flags have been cleared by the time we get to this + // pass, but it is safe to assume that all uses of this register + // occur in the same basic block as its definition, because + // it is illegal for the scheduler to schedule them in + // different blocks. + if (UseI->findRegisterUseOperandIdx(MOI->getReg())) + LastUseCount = AluInstCount; + + if (UseI != Def && UseI->findRegisterDefOperandIdx(MOI->getReg()) != -1) + break; + } + if (LastUseCount) + return LastUseCount <= TII->getMaxAlusPerClause(); + llvm_unreachable("Clause local register live at end of clause."); + } + return true; + } + MachineBasicBlock::iterator MakeALUClause(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) { MachineBasicBlock::iterator ClauseHead = I; @@ -198,11 +261,13 @@ private: I++; break; } - if (TII->isALUInstr(I->getOpcode()) && - !SubstituteKCacheBank(I, KCacheBanks)) + + // If this instruction defines a clause local register, make sure + // its use can fit in this clause. + if (!canClauseLocalKillFitInClause(AluInstCount, KCacheBanks, I, E)) break; - if (I->getOpcode() == AMDGPU::DOT_4 && - !SubstituteKCacheBank(I, KCacheBanks)) + + if (!SubstituteKCacheBank(I, KCacheBanks)) break; AluInstCount += OccupiedDwords(I); } @@ -226,11 +291,14 @@ private: } public: - R600EmitClauseMarkersPass(TargetMachine &tm) : MachineFunctionPass(ID), - TII(0), Address(0) { } + static char ID; + R600EmitClauseMarkers() : MachineFunctionPass(ID), TII(nullptr), Address(0) { + + initializeR600EmitClauseMarkersPass(*PassRegistry::getPassRegistry()); + } - virtual bool runOnMachineFunction(MachineFunction &MF) { - TII = static_cast(MF.getTarget().getInstrInfo()); + bool runOnMachineFunction(MachineFunction &MF) override { + TII = static_cast(MF.getSubtarget().getInstrInfo()); for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end(); BB != BB_E; ++BB) { @@ -248,17 +316,21 @@ public: return false; } - const char *getPassName() const { + const char *getPassName() const override { return "R600 Emit Clause Markers Pass"; } }; -char R600EmitClauseMarkersPass::ID = 0; +char R600EmitClauseMarkers::ID = 0; } // end anonymous namespace +INITIALIZE_PASS_BEGIN(R600EmitClauseMarkers, "emitclausemarkers", + "R600 Emit Clause Markters", false, false) +INITIALIZE_PASS_END(R600EmitClauseMarkers, "emitclausemarkers", + "R600 Emit Clause Markters", false, false) -llvm::FunctionPass *llvm::createR600EmitClauseMarkers(TargetMachine &TM) { - return new R600EmitClauseMarkersPass(TM); +llvm::FunctionPass *llvm::createR600EmitClauseMarkers() { + return new R600EmitClauseMarkers(); }