Skip to content

Commit c40c8a2

Browse files
dmitryryinteligcbot
authored andcommitted
move splitStructPhis implementation to the proper place
1 parent 719aae1 commit c40c8a2

File tree

3 files changed

+74
-77
lines changed

3 files changed

+74
-77
lines changed

IGC/VectorCompiler/lib/GenXCodeGen/GenXLowering.cpp

-76
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ class GenXLowering : public FunctionPass {
160160
virtual StringRef getPassName() const { return "GenX lowering"; }
161161
void getAnalysisUsage(AnalysisUsage &AU) const;
162162
bool runOnFunction(Function &F);
163-
static bool splitStructPhi(PHINode *Phi);
164163

165164
private:
166165
bool splitGatherScatter(CallInst *CI, unsigned IID);
@@ -2196,81 +2195,6 @@ Instruction *llvm::genx::convertShlShr(Instruction *Inst) {
21962195
return Ext;
21972196
}
21982197

2199-
/***********************************************************************
2200-
* splitStructPhis : find struct phi nodes and split them
2201-
*
2202-
* Return: whether code modified
2203-
*
2204-
* Each struct phi node is split into a separate phi node for each struct
2205-
* element. This is needed because the GenX backend's liveness and coalescing
2206-
* code cannot cope with a struct phi.
2207-
*
2208-
* This is run in two places: firstly in GenXLowering, so that pass can then
2209-
* simplify any InsertElement and ExtractElement instructions added by the
2210-
* struct phi splitting. But then it needs to be run again in GenXLiveness,
2211-
* because other passes can re-insert a struct phi. The case I saw in
2212-
* hevc_speed was something commoning up the struct return from two calls in an
2213-
* if..else..endif.
2214-
*/
2215-
bool genx::splitStructPhis(Function *F) {
2216-
bool Modified = false;
2217-
for (Function::iterator fi = F->begin(), fe = F->end(); fi != fe; ++fi) {
2218-
BasicBlock *BB = &*fi;
2219-
for (BasicBlock::iterator bi = BB->begin();;) {
2220-
PHINode *Phi = dyn_cast<PHINode>(&*bi);
2221-
if (!Phi)
2222-
break;
2223-
++bi; // increment here as splitStructPhi removes old phi node
2224-
if (isa<StructType>(Phi->getType()))
2225-
Modified |= GenXLowering::splitStructPhi(Phi);
2226-
}
2227-
}
2228-
return Modified;
2229-
}
2230-
2231-
/***********************************************************************
2232-
* splitStructPhi : split a phi node with struct type by splitting into
2233-
* struct elements
2234-
*/
2235-
bool GenXLowering::splitStructPhi(PHINode *Phi) {
2236-
StructType *Ty = cast<StructType>(Phi->getType());
2237-
// Find where we need to insert the combine instructions.
2238-
Instruction *CombineInsertBefore = Phi->getParent()->getFirstNonPHI();
2239-
// Now split the phi.
2240-
Value *Combined = UndefValue::get(Ty);
2241-
// For each struct element...
2242-
for (unsigned Idx = 0, e = Ty->getNumElements(); Idx != e; ++Idx) {
2243-
Type *ElTy = Ty->getTypeAtIndex(Idx);
2244-
// Create the new phi node.
2245-
PHINode *NewPhi =
2246-
PHINode::Create(ElTy, Phi->getNumIncomingValues(),
2247-
Phi->getName() + ".element" + Twine(Idx), Phi);
2248-
NewPhi->setDebugLoc(Phi->getDebugLoc());
2249-
// Combine the new phi.
2250-
Instruction *Combine = InsertValueInst::Create(
2251-
Combined, NewPhi, Idx, NewPhi->getName(), CombineInsertBefore);
2252-
Combine->setDebugLoc(Phi->getDebugLoc());
2253-
Combined = Combine;
2254-
// For each incoming...
2255-
for (unsigned In = 0, InEnd = Phi->getNumIncomingValues(); In != InEnd;
2256-
++In) {
2257-
// Create an extractelement to get the individual element value.
2258-
// This needs to go before the terminator of the incoming block.
2259-
BasicBlock *IncomingBB = Phi->getIncomingBlock(In);
2260-
Value *Incoming = Phi->getIncomingValue(In);
2261-
Instruction *Extract = ExtractValueInst::Create(
2262-
Incoming, Idx, Phi->getName() + ".element" + Twine(Idx),
2263-
IncomingBB->getTerminator());
2264-
Extract->setDebugLoc(Phi->getDebugLoc());
2265-
// Add as an incoming of the new phi node.
2266-
NewPhi->addIncoming(Extract, IncomingBB);
2267-
}
2268-
}
2269-
Phi->replaceAllUsesWith(Combined);
2270-
Phi->eraseFromParent();
2271-
return true;
2272-
}
2273-
22742198
/***********************************************************************
22752199
* lowerExtractValue : remove extractvalue if possible
22762200
*

IGC/VectorCompiler/lib/GenXCodeGen/GenXUtil.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -2018,3 +2018,60 @@ std::size_t genx::getStructElementPaddedSize(unsigned ElemIdx,
20182018
return Layout.getElementOffset(ElemIdx + 1) -
20192019
Layout.getElementOffset(ElemIdx);
20202020
}
2021+
2022+
// splitStructPhi : split a phi node with struct type by splitting into
2023+
// struct elements
2024+
bool genx::splitStructPhi(PHINode *Phi) {
2025+
StructType *Ty = cast<StructType>(Phi->getType());
2026+
// Find where we need to insert the combine instructions.
2027+
Instruction *CombineInsertBefore = Phi->getParent()->getFirstNonPHI();
2028+
// Now split the phi.
2029+
Value *Combined = UndefValue::get(Ty);
2030+
// For each struct element...
2031+
for (unsigned Idx = 0, e = Ty->getNumElements(); Idx != e; ++Idx) {
2032+
Type *ElTy = Ty->getTypeAtIndex(Idx);
2033+
// Create the new phi node.
2034+
PHINode *NewPhi =
2035+
PHINode::Create(ElTy, Phi->getNumIncomingValues(),
2036+
Phi->getName() + ".element" + Twine(Idx), Phi);
2037+
NewPhi->setDebugLoc(Phi->getDebugLoc());
2038+
// Combine the new phi.
2039+
Instruction *Combine = InsertValueInst::Create(
2040+
Combined, NewPhi, Idx, NewPhi->getName(), CombineInsertBefore);
2041+
Combine->setDebugLoc(Phi->getDebugLoc());
2042+
Combined = Combine;
2043+
// For each incoming...
2044+
for (unsigned In = 0, InEnd = Phi->getNumIncomingValues(); In != InEnd;
2045+
++In) {
2046+
// Create an extractelement to get the individual element value.
2047+
// This needs to go before the terminator of the incoming block.
2048+
BasicBlock *IncomingBB = Phi->getIncomingBlock(In);
2049+
Value *Incoming = Phi->getIncomingValue(In);
2050+
Instruction *Extract = ExtractValueInst::Create(
2051+
Incoming, Idx, Phi->getName() + ".element" + Twine(Idx),
2052+
IncomingBB->getTerminator());
2053+
Extract->setDebugLoc(Phi->getDebugLoc());
2054+
// Add as an incoming of the new phi node.
2055+
NewPhi->addIncoming(Extract, IncomingBB);
2056+
}
2057+
}
2058+
Phi->replaceAllUsesWith(Combined);
2059+
Phi->eraseFromParent();
2060+
return true;
2061+
}
2062+
2063+
bool genx::splitStructPhis(Function *F) {
2064+
bool Modified = false;
2065+
for (Function::iterator fi = F->begin(), fe = F->end(); fi != fe; ++fi) {
2066+
BasicBlock *BB = &*fi;
2067+
for (BasicBlock::iterator bi = BB->begin();;) {
2068+
PHINode *Phi = dyn_cast<PHINode>(&*bi);
2069+
if (!Phi)
2070+
break;
2071+
++bi; // increment here as splitStructPhi removes old phi node
2072+
if (isa<StructType>(Phi->getType()))
2073+
Modified |= splitStructPhi(Phi);
2074+
}
2075+
}
2076+
return Modified;
2077+
}

IGC/VectorCompiler/lib/GenXCodeGen/GenXUtil.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,24 @@ Instruction *findClosestCommonDominator(DominatorTree *DT,
105105
// trunc+sext/zext
106106
Instruction *convertShlShr(Instruction *Inst);
107107

108-
// splitStructPhis : split all struct phis in a function
108+
// splitStructPhis : find struct phi nodes and split them
109+
//
110+
// Return: whether code modified
111+
//
112+
// Each struct phi node is split into a separate phi node for each struct
113+
// element. This is needed because the GenX backend's liveness and coalescing
114+
// code cannot cope with a struct phi.
115+
//
116+
// This is run in two places: firstly in GenXLowering, so that pass can then
117+
// simplify any InsertElement and ExtractElement instructions added by the
118+
// struct phi splitting. But then it needs to be run again in GenXLiveness,
119+
// because other passes can re-insert a struct phi. The case I saw in
120+
// hevc_speed was something commoning up the struct return from two calls in an
121+
// if..else..endif.
122+
//
123+
// BTW There's also GenXAggregatePseudoLowering pass that does the same.
109124
bool splitStructPhis(Function *F);
125+
bool splitStructPhi(PHINode *Phi);
110126

111127
// normalize g_load with bitcasts.
112128
//

0 commit comments

Comments
 (0)