Skip to content

Commit

Permalink
Remove unnecessary MOVs
Browse files Browse the repository at this point in the history
 Unnecessary MOVs were removed from ASM.
  • Loading branch information
adam-bzowski authored and igcbot committed Sep 25, 2024
1 parent a720c93 commit 45f7f00
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 24 deletions.
85 changes: 62 additions & 23 deletions IGC/Compiler/CISACodeGen/EmitVISAPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1537,10 +1537,40 @@ void EmitPass::MovPhiSources(llvm::BasicBlock* aBB)
Value* dstRootV; // root value of dst (dessa)
Value* srcRootV; // root value of src (dessa)
};

struct VTyInfo {
unsigned numElt;
bool isSplat;
uint64_t splatValue;

VTyInfo() : numElt(0), isSplat(false), splatValue(0) { }
explicit VTyInfo(Value * V) : numElt(0), isSplat(false), splatValue(0) {
if (IGCLLVM::FixedVectorType * vTy = dyn_cast<IGCLLVM::FixedVectorType>(V->getType())) {
numElt = vTy->getNumElements();
if (isa<ConstantAggregateZero>(V)) {
isSplat = true;
splatValue = 0;
}
else if (ConstantDataVector * CDV = dyn_cast<ConstantDataVector>(V)) {
if (Constant * C = CDV->getSplatValue()) {
if (ConstantInt * CInt = dyn_cast<ConstantInt>(C)) {
isSplat = true;
splatValue = CInt->getZExtValue();
}
else if (ConstantFP * CFP = dyn_cast<ConstantFP>(C)) {
isSplat = true;
splatValue = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
}
}
}
}
}
};

BumpPtrAllocator phiAllocator;
std::list<PhiSrcMoveInfo*> phiSrcDstList;
std::vector<std::pair<CVariable*, CVariable*>> emitList;
std::map<CVariable*, unsigned int> dstVTyMap;
std::map<CVariable*, VTyInfo> dstVTyMap;
llvm::BasicBlock* bb = aBB;
IGCLLVM::TerminatorInst* TI = aBB->getTerminator();
IGC_ASSERT(nullptr != TI);
Expand All @@ -1565,7 +1595,6 @@ void EmitPass::MovPhiSources(llvm::BasicBlock* aBB)
if (PN->getIncomingBlock(i) == bb)
{
Value* Src = PN->getOperand(i);

Value* dstRootV = m_deSSA ? m_deSSA->getRootValue(PN) : PN;
Value* srcRootV = m_deSSA ? m_deSSA->getRootValue(Src) : Src;
dstRootV = dstRootV ? dstRootV : PN;
Expand All @@ -1575,19 +1604,14 @@ void EmitPass::MovPhiSources(llvm::BasicBlock* aBB)
// might have the same variable with two different CVariable.
if (dstRootV != srcRootV)
{
VTyInfo vTyInfo(Src);
PhiSrcMoveInfo* phiInfo = new (phiAllocator) PhiSrcMoveInfo();
phiInfo->srcCVar = vTyInfo.isSplat ? nullptr : m_currShader->GetSymbol(Src);
phiInfo->dstCVar = m_currShader->GetSymbol(PN);
phiInfo->srcCVar = m_currShader->GetSymbol(Src);
phiInfo->dstRootV = dstRootV;
phiInfo->srcRootV = srcRootV;
phiSrcDstList.push_back(phiInfo);

int numElt = 0;
if (IGCLLVM::FixedVectorType * vTy = dyn_cast<IGCLLVM::FixedVectorType>(PN->getType()))
{
numElt = int_cast<int>(vTy->getNumElements());
}
dstVTyMap.insert(std::pair<CVariable*, unsigned int>(phiInfo->dstCVar, numElt));
dstVTyMap.insert(std::make_pair(phiInfo->dstCVar, vTyInfo));
}
}
}
Expand Down Expand Up @@ -1651,14 +1675,16 @@ void EmitPass::MovPhiSources(llvm::BasicBlock* aBB)
if (phiinfo->srcRootV == dRootV) {
CVariable* sVar = phiinfo->srcCVar;
CVariable* nVar;
if (sVar->GetType() != T->GetType()) {
nVar = m_currShader->GetNewAlias(
T, sVar->GetType(), 0, sVar->GetNumberElement());
}
else {
nVar = T;
if (sVar) { // sVar is null if srcCVar is a constant splat vector
if (sVar->GetType() != T->GetType()) {
nVar = m_currShader->GetNewAlias(
T, sVar->GetType(), 0, sVar->GetNumberElement());
}
else {
nVar = T;
}
phiinfo->srcCVar = nVar;
}
phiinfo->srcCVar = nVar;
}
}
}
Expand Down Expand Up @@ -1688,13 +1714,14 @@ void EmitPass::MovPhiSources(llvm::BasicBlock* aBB)
for (uint instance = 0; instance < dst->GetNumberInstance(); instance++)
{
m_encoder->SetSecondHalf(instance == 1 ? true : false);
unsigned int numVTyElt = dstVTyMap[dst];
if (numVTyElt > 0)
{
emitVectorCopy(dst, src, numVTyElt);
const VTyInfo & vTyInfo = dstVTyMap[dst];
if (vTyInfo.isSplat) {
emitConstantVector(dst, vTyInfo.splatValue);
}
else
{
else if (vTyInfo.numElt > 0) {
emitVectorCopy(dst, src, vTyInfo.numElt);
}
else {
m_encoder->Copy(dst, src);
m_encoder->Push();
}
Expand Down Expand Up @@ -20103,6 +20130,18 @@ void EmitPass::emitVectorCopy(CVariable* Dst, CVariable* Src, uint32_t nElts,
}
}

void EmitPass::emitConstantVector(CVariable* Dst, uint64_t value)
{
uint16_t width = Dst->IsUniform() ? 1 : numLanes(m_currShader->m_SIMDSize);
CVariable * constant = m_currShader->ImmToVariable(value, Dst->GetType());
for (uint16_t i = 0; width * i < Dst->GetNumberElement(); ++i)
{
m_encoder->SetDstSubReg(width * i);
m_encoder->Copy(Dst, constant);
m_encoder->Push();
}
}

//emitVectorCopyToOrFromAOS()
// To implement the follow two functions.
// emitVectorCopyToAOS(): IsToAOS = true
Expand Down
1 change: 1 addition & 0 deletions IGC/Compiler/CISACodeGen/EmitVISAPass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ class EmitPass : public llvm::FunctionPass
void emitVectorCopy(CVariable* Dst, CVariable* Src, uint32_t nElts,
uint32_t DstSubRegOffset = 0, uint32_t SrcSubRegOffset = 0,
bool allowLargerSIMDSize = false);
void emitConstantVector(CVariable* Dst, uint64_t value = 0);
void emitCopyAll(CVariable* Dst, CVariable* Src, llvm::Type* Ty);

void emitPushFrameToStack(Function* ParentFunction, unsigned& pushSize);
Expand Down
7 changes: 6 additions & 1 deletion IGC/Compiler/CISACodeGen/VariableReuseAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,12 @@ void VariableReuseAnalysis::InsertElementAliasing(Function* F)
// =0x2: subvec aliasing for both isolated and non-isolated value)
const auto control = (m_pCtx->getVectorCoalescingControl() & 0x3);
// To avoid increasing GRF pressure, skip if F is too large or not an entry
const int32_t NumBBThreshold = (int)IGC_GET_FLAG_VALUE(VectorAliasBBThreshold);
// We remove the threshold when the code comes from CUTLASS,
// which often generates a large number of basic blocks.
const int32_t NumBBThreshold =
F->getName().str().substr(0, 2) == "_Z" && F->getName().str().find("cutlass") != std::string::npos
? std::numeric_limits<int32_t>::max()
: static_cast<int32_t>(IGC_GET_FLAG_VALUE(VectorAliasBBThreshold));
MetaDataUtils* pMdUtils = getAnalysis<MetaDataUtilsWrapper>().getMetaDataUtils();
if (control == 0 || !isEntryFunc(pMdUtils, F) || getNumBBs(F) > NumBBThreshold) {
return;
Expand Down

0 comments on commit 45f7f00

Please sign in to comment.