Skip to content

Commit c3f247b

Browse files
pratikasharigcbot
authored andcommitted
[Autobackout][FuncReg]Revert of change: 932be31
Restrict augmentation live-intervals to "home" function only Consider following program: main: a = call foo = a b = call foo = b foo: c = 1 return a, b are both live in foo due to IPA. Howver, their liveness is temporally disjoint so they shouldn't be marked as interfering. However, a and c as well as b and c must be marked as interfering. As per logic prior to this PR, 2 sub-intervals will be created for a (b). First live-interval extends from definition of a (b) to use and second on exists from start to end of foo() given that a (b) is live-in/live-out of foo(). This PR introduces concept of "home" function. Each G4_Declare has a "home" function that's either nullptr or pointer to an actual FuncInfo* instance. When a G4_Declare is defined or used in a single function, its "home" function is set to that function's FuncInfo instance. Whereas when a G4_Declare is referenced in multiple functions (eg, kernel and sub), its "home" function is not unique and is set to nullptr. In augmentation, live-interval construction for a variable depends on its "home" function. If "home" function is set to nullptr (ie, args, retval) then live-intervals are constructed across functions. This means one sub-interval may be in one function and another sub-interval may be in another function. Whereas when "home" location contains a non-nullptr value, we restrict live-intervals to only be contained in "home" function. It means that in above example, variables a and b have their home location set to kernel and a single non-overlapping live-interval is created for each. Since no live-interval is created for these in function foo(), they don't overlap and therefore there's no interference between them.
1 parent 15553d6 commit c3f247b

File tree

5 files changed

+16
-210
lines changed

5 files changed

+16
-210
lines changed

visa/GraphColor.cpp

Lines changed: 11 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -2770,56 +2770,6 @@ void GlobalRA::getBankAlignment(LiveRange *lr, BankAlign &align) {
27702770
}
27712771
}
27722772

2773-
// Compute homeFunc for dcl. Following rules are used:
2774-
// 1. A variable that's defined or used in a single function has
2775-
// that function as its home function.
2776-
// 2. A variable that's defined or used across functions (eg,
2777-
// args, retval) have their home function set to nullptr.
2778-
// 3. homeFunc is set only on root G4_Declare.
2779-
FuncInfo *Augmentation::computeHomeFunc(G4_Declare *dcl) {
2780-
vISA_ASSERT(!dcl->getAliasDeclare(), "root dcl expected");
2781-
// If there are no subroutines then all dcls have kernel as home function
2782-
if (!hasSubroutines)
2783-
return kernel.fg.kernelInfo;
2784-
2785-
if (hasUniqueFuncHome(dcl))
2786-
return getUniqueFuncHome(dcl);
2787-
2788-
FuncInfo *homeFunction = nullptr;
2789-
// Live-ins to kernel are modeled as being implicitly defined in kernel.
2790-
if (dcl->isInput())
2791-
homeFunction = kernel.fg.kernelInfo;
2792-
auto *defs = refs.getDefs(dcl);
2793-
if (defs) {
2794-
for (auto &def : *defs) {
2795-
auto *bb = std::get<1>(def);
2796-
auto *curDefFunc = bbToFunc.at(bb);
2797-
if (!homeFunction) {
2798-
homeFunction = curDefFunc;
2799-
continue;
2800-
} else if (homeFunction != curDefFunc) {
2801-
return nullptr;
2802-
}
2803-
}
2804-
}
2805-
2806-
auto *uses = refs.getUses(dcl);
2807-
if (uses) {
2808-
for (auto &use : *uses) {
2809-
auto *bb = std::get<1>(use);
2810-
auto *curUseFunc = bbToFunc.at(bb);
2811-
if (!homeFunction) {
2812-
homeFunction = curUseFunc;
2813-
continue;
2814-
} else if (homeFunction != curUseFunc) {
2815-
return nullptr;
2816-
}
2817-
}
2818-
}
2819-
2820-
return homeFunction;
2821-
}
2822-
28232773
void Augmentation::populateFuncMaps() {
28242774
vISA_ASSERT(kernel.fg.getBBList().back()->size() > 0, "last BB empty");
28252775
instToFunc.resize(kernel.fg.getBBList().back()->back()->getLexicalId() + 1);
@@ -2833,24 +2783,10 @@ void Augmentation::populateFuncMaps() {
28332783
}
28342784
}
28352785

2836-
void Augmentation::populateHomeFunc() {
2837-
// Assume last G4_Declare has max declId
2838-
homeFunc.resize(kernel.Declares.back()->getDeclId() + 1);
2839-
for (auto dcl : kernel.Declares) {
2840-
if (dcl->getAliasDeclare())
2841-
dcl = dcl->getRootDeclare();
2842-
auto *func = computeHomeFunc(dcl);
2843-
vISA_ASSERT(!hasUniqueFuncHome(dcl) || getUniqueFuncHome(dcl) == func,
2844-
"different home func set");
2845-
homeFunc[dcl->getDeclId()] = func;
2846-
}
2847-
}
2848-
28492786
Augmentation::Augmentation(Interference &i, const LivenessAnalysis &l,
28502787
GlobalRA &g)
28512788
: kernel(g.kernel), intf(i), gra(g), liveAnalysis(l), lrs(g.incRA.getLRs()),
2852-
fcallRetMap(g.fcallRetMap),
2853-
refs(g.kernel, false, false, true, &g.pointsToAnalysis),
2789+
fcallRetMap(g.fcallRetMap), refs(g.kernel, false, false, true),
28542790
hasSubroutines(kernel.fg.sortedFuncTable.size() > 0 &&
28552791
g.kernel.getOption(vISA_NewAugmentation)) {
28562792
useGenericAugAlign =
@@ -3877,16 +3813,6 @@ void Augmentation::buildUnknownArgRetval() {
38773813
}
38783814
}
38793815

3880-
bool Augmentation::hasUniqueFuncHome(G4_Declare *dcl) const {
3881-
auto *homeFunction = homeFunc[dcl->getDeclId()];
3882-
return homeFunction != nullptr;
3883-
}
3884-
3885-
FuncInfo* Augmentation::getUniqueFuncHome(G4_Declare* dcl) const {
3886-
vISA_ASSERT(hasUniqueFuncHome(dcl), "expecting unique home func");
3887-
return homeFunc[dcl->getDeclId()];
3888-
}
3889-
38903816
void Augmentation::startIntervalForLiveIn(FuncInfo *funcInfo, G4_BB *bb) {
38913817
// Start live-in intervals
38923818
auto liveInBB = liveAnalysis.getLiveAtEntry(bb) & liveAnalysis.globalVars;
@@ -3895,9 +3821,6 @@ void Augmentation::startIntervalForLiveIn(FuncInfo *funcInfo, G4_BB *bb) {
38953821
if (isUnknownArgOrRetval(dcl))
38963822
continue;
38973823

3898-
if (hasUniqueFuncHome(dcl) && getUniqueFuncHome(dcl) != funcInfo)
3899-
continue;
3900-
39013824
vISA_ASSERT(bb->size() > 0, "empty instlist");
39023825
vISA_ASSERT(funcInfo == kernel.fg.kernelInfo ||
39033826
argsPerSub.count(funcInfo) > 0 ||
@@ -4099,7 +4022,7 @@ void Augmentation::handlePred(FuncInfo* funcInfo, G4_INST *inst) {
40994022
}
41004023
}
41014024

4102-
void Augmentation::endIntervalForLiveOut(FuncInfo* funcInfo, G4_BB *bb) {
4025+
void Augmentation::endIntervalForLiveOut(G4_BB *bb) {
41034026
auto liveOutBB = liveAnalysis.getLiveAtExit(bb) & liveAnalysis.globalVars;
41044027
if (bb->isEndWithCall() && liveAnalysis.livenessClass(G4_GRF)) {
41054028
// reset bit for RET__loc as we handle it specially later to
@@ -4127,10 +4050,6 @@ void Augmentation::endIntervalForLiveOut(FuncInfo* funcInfo, G4_BB *bb) {
41274050
G4_Declare *dcl = lrs[i]->getDcl()->getRootDeclare();
41284051
if (isUnknownArgOrRetval(dcl))
41294052
continue;
4130-
4131-
if (hasUniqueFuncHome(dcl) && getUniqueFuncHome(dcl) != funcInfo)
4132-
continue;
4133-
41344053
vISA_ASSERT(bb->size() > 0, "empty instlist");
41354054
updateEndInterval(dcl, bb->back());
41364055
}
@@ -4160,7 +4079,7 @@ void Augmentation::handleNonReducibleExtension(FuncInfo *funcInfo) {
41604079
}
41614080
}
41624081
for (auto exitBB : SCCSucc) {
4163-
extendVarLiveness(funcInfo, exitBB, headBB->front());
4082+
extendVarLiveness(exitBB, headBB->front());
41644083
}
41654084
}
41664085
}
@@ -4199,7 +4118,7 @@ void Augmentation::handleLoopExtension(FuncInfo *funcInfo) {
41994118
std::cout << "==> Extend live-in for BB" << exitBB->getId() << "\n";
42004119
exitBB->emit(std::cout);
42014120
});
4202-
extendVarLiveness(funcInfo, exitBB, startInst);
4121+
extendVarLiveness(exitBB, startInst);
42034122
}
42044123
}
42054124
}
@@ -4214,10 +4133,6 @@ void Augmentation::handleLoopExtension(FuncInfo *funcInfo) {
42144133

42154134
for (auto i : globalsLiveInAndLiveOut) {
42164135
auto *dcl = lrs[i]->getDcl()->getRootDeclare();
4217-
// If dcl has non-nullptr home function then extend liveness only
4218-
// in same function.
4219-
if (hasUniqueFuncHome(dcl) && getUniqueFuncHome(dcl) != funcInfo)
4220-
continue;
42214136

42224137
updateEndInterval(dcl, endBB->back());
42234138
VISA_DEBUG_VERBOSE({
@@ -4235,16 +4150,11 @@ void Augmentation::handleLoopExtension(FuncInfo *funcInfo) {
42354150
}
42364151

42374152
// Extend all variables that are live at bb entry to the given inst
4238-
void Augmentation::extendVarLiveness(FuncInfo *funcInfo, G4_BB *bb,
4239-
G4_INST *inst) {
4153+
void Augmentation::extendVarLiveness(G4_BB *bb, G4_INST *inst) {
42404154
auto liveAtEntryBB =
42414155
liveAnalysis.getLiveAtEntry(bb) & liveAnalysis.globalVars;
42424156
for (auto i : liveAtEntryBB) {
42434157
G4_Declare *dcl = lrs[i]->getDcl()->getRootDeclare();
4244-
// If dcl has non-nullptr home function then extend liveness only
4245-
// in same function.
4246-
if (hasUniqueFuncHome(dcl) && getUniqueFuncHome(dcl) != funcInfo)
4247-
continue;
42484158

42494159
if (!kernel.fg.isPseudoDcl(dcl)) {
42504160
// Extend ith live-interval
@@ -4271,7 +4181,7 @@ void Augmentation::buildLiveIntervals(FuncInfo* funcInfo) {
42714181
for (G4_BB *curBB : funcInfo->getBBList()) {
42724182
if (!curBB->empty()) {
42734183
startIntervalForLiveIn(funcInfo, curBB);
4274-
endIntervalForLiveOut(funcInfo, curBB);
4184+
endIntervalForLiveOut(curBB);
42754185
}
42764186

42774187
for (G4_INST *inst : *curBB) {
@@ -5131,8 +5041,6 @@ void Augmentation::discoverRetVal(FuncInfo *func) {
51315041
retValPerSub[func].insert(dcl);
51325042
if (retValInfo.subroutines.size() > 1)
51335043
retValInfo.retValType = RetValType::Unknown;
5134-
vISA_ASSERT(!hasUniqueFuncHome(dcl),
5135-
"retval cannot have non-nullptr home function");
51365044
}
51375045

51385046
if (kernel.getOption(vISA_VerifyAugmentation)) {
@@ -5149,8 +5057,7 @@ void Augmentation::discoverArgs(FuncInfo *func) {
51495057

51505058
SparseBitVector subArgs;
51515059
if (func == kernel.fg.kernelInfo)
5152-
subArgs = liveAnalysis.use_in[kernel.fg.getEntryBB()->getId()] &
5153-
liveAnalysis.def_in[kernel.fg.getEntryBB()->getId()];
5060+
subArgs = liveAnalysis.use_in[kernel.fg.getEntryBB()->getId()];
51545061
else
51555062
subArgs = liveAnalysis.args.at(func);
51565063

@@ -5167,10 +5074,6 @@ void Augmentation::discoverArgs(FuncInfo *func) {
51675074
if (argInfo.subroutines.size() > 1 &&
51685075
argInfo.argType == ArgType::DefBeforeEachCall)
51695076
argInfo.argType = ArgType::Unknown;
5170-
vISA_ASSERT(
5171-
argInfo.argType != ArgType::DefBeforeEachCall ||
5172-
!hasUniqueFuncHome(dcl),
5173-
"def before each call arg cannot have non-nullptr home function");
51745077
}
51755078

51765079

@@ -5210,16 +5113,6 @@ void Augmentation::dumpSortedIntervals() {
52105113
std::cout << " (LiveThroughArg)";
52115114
else if (isRegularRetVal(dcl))
52125115
std::cout << " (RegularRetVal)";
5213-
if (dcl->getDeclId() >= homeFunc.size()) {
5214-
std::cout << " @ (new var)";
5215-
}
5216-
else {
5217-
auto *homeFunction = homeFunc[dcl->getDeclId()];
5218-
if (!homeFunction)
5219-
std::cout << " @ (global)";
5220-
else
5221-
std::cout << " @ (func " << (int)homeFunction->getId() << ")";
5222-
}
52235116
std::cout << " - (" << gra.getIntervalStart(interval)->getLexicalId()
52245117
<< ", " << gra.getIntervalEnd(interval)->getLexicalId() << "]";
52255118
if (intervalsPerVar[dcl].size() > 1) {
@@ -5679,17 +5572,16 @@ void Augmentation::augmentIntfGraph() {
56795572
bool nonDefaultMaskDef = markNonDefaultMaskDef();
56805573

56815574
if (nonDefaultMaskDef == true) {
5682-
if (augWithHoles) {
5683-
if (kernel.fg.getNumFuncs() > 0)
5684-
populateFuncMaps();
5685-
5686-
populateHomeFunc();
5575+
if (augWithHoles && kernel.fg.getNumFuncs() > 0)
5576+
populateFuncMaps();
56875577

5578+
if (augWithHoles) {
56885579
// Atleast one definition with non-default mask was found so
56895580
// perform steps to augment intf graph with such defs
56905581

56915582
// Discover and store subroutine arguments
56925583
if (hasSubroutines) {
5584+
56935585
for (auto &subroutine : kernel.fg.sortedFuncTable) {
56945586
discoverArgs(subroutine);
56955587
discoverRetVal(subroutine);

visa/GraphColor.h

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -429,17 +429,6 @@ class Augmentation {
429429
std::unordered_map<G4_Declare *, std::unordered_set<FuncInfo *>> unknownArgRetvalRefs;
430430
std::unordered_map<G4_Declare *, std::unordered_set<FuncInfo *>> nonGRFRefs;
431431
std::unordered_map<G4_BB *, FuncInfo *> bbToFunc;
432-
// Store home function for given variable. Home function is defined as
433-
// function that contains explicit def or use of the variable. Each regular
434-
// variable has a unique home function. Arg/retval don't have a unique home
435-
// function as they're usually defined in caller and used in callee, ie
436-
// they're referenced in different functions.
437-
//
438-
// This vector is indexed by G4_Declare's dclId.
439-
//
440-
// It's assumed that augmentation doesn't require resizing this vector
441-
// despite inserting new SCALL dcls as they're all function local.
442-
std::vector<FuncInfo *> homeFunc;
443432
// Sadly, we don't have a way to map G4_INST to containing G4_BB.
444433
// So we create it in Augmentation using below vector. To get
445434
// FuncInfo* for a G4_INST, we dereference instToFunc using
@@ -450,7 +439,6 @@ class Augmentation {
450439
const bool hasSubroutines = false;
451440

452441
void populateFuncMaps();
453-
void populateHomeFunc();
454442
bool isSubroutineArg(G4_Declare *dcl) const {
455443
auto it = argsRetVal.find(dcl);
456444
if (it == argsRetVal.end())
@@ -496,11 +484,6 @@ class Augmentation {
496484
bool isUnknownRetVal(G4_Declare *dcl) const;
497485
bool isRegularRetVal(G4_Declare *dcl) const;
498486
bool isUnknownArgOrRetval(G4_Declare *dcl) const;
499-
FuncInfo *computeHomeFunc(G4_Declare *dcl);
500-
bool hasUniqueFuncHome(G4_Declare *dcl) const;
501-
FuncInfo *getUniqueFuncHome(G4_Declare *dcl) const;
502-
503-
void verifyHomeLocation();
504487

505488
bool updateDstMaskForGather(G4_INST *inst, std::vector<unsigned char> &mask);
506489
bool updateDstMaskForGatherRaw(G4_INST *inst,
@@ -539,12 +522,12 @@ class Augmentation {
539522
void handleCallSite(G4_BB *curBB, unsigned int &funcCnt);
540523
void handleDstOpnd(FuncInfo *funcInfo, G4_BB *curBB, G4_INST *inst);
541524
void handleCondMod(FuncInfo* funcInfo, G4_INST *inst);
542-
void endIntervalForLiveOut(FuncInfo *funcInfo, G4_BB *bb);
525+
void endIntervalForLiveOut(G4_BB *bb);
543526
void handleSrcOpnd(FuncInfo *funcInfo, G4_BB *curBB, G4_Operand *src);
544527
void handlePred(FuncInfo* funcInfo, G4_INST *inst);
545528
void handleNonReducibleExtension(FuncInfo *funcInfo);
546529
void handleLoopExtension(FuncInfo *funcInfo);
547-
void extendVarLiveness(FuncInfo *funcInfo, G4_BB *bb, G4_INST *inst);
530+
void extendVarLiveness(G4_BB *bb, G4_INST *inst);
548531
unsigned getEnd(const G4_Declare *dcl) const;
549532
bool isNoMask(const G4_Declare *dcl, unsigned size) const;
550533
bool isConsecutiveBits(const G4_Declare *dcl, unsigned size) const;

visa/LoopAnalysis.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ SPDX-License-Identifier: MIT
1111
#include "BitSet.h"
1212
#include "G4_BB.hpp"
1313
#include "G4_Kernel.hpp"
14-
#include "PointsToAnalysis.h"
1514

1615
using namespace vISA;
1716

@@ -1033,17 +1032,6 @@ void VarReferences::run() {
10331032
auto &Defs = VarRefs[topdcl].first;
10341033
Defs.push_back(std::make_tuple(inst, bb, lb, rb));
10351034
}
1036-
1037-
if (p2a && dst->isIndirect()) {
1038-
auto *pointees = p2a->getAllInPointsTo(topdcl->getRegVar());
1039-
vISA_ASSERT(pointees, "expecting valid pointee list");
1040-
for (const auto& pointee : *pointees) {
1041-
auto &Defs = VarRefs[pointee.var->getDeclare()->getRootDeclare()].first;
1042-
// lb, rb are both unknown for indirects
1043-
Defs.push_back(
1044-
std::make_tuple(inst, bb, UnknownBound, UnknownBound));
1045-
}
1046-
}
10471035
}
10481036

10491037
if (!onlyGRF) {
@@ -1069,16 +1057,6 @@ void VarReferences::run() {
10691057
auto &Uses = VarRefs[topdcl].second;
10701058
Uses.push_back(std::make_tuple(inst, bb));
10711059
}
1072-
1073-
if (p2a && src->isIndirect()) {
1074-
auto *pointees = p2a->getAllInPointsTo(topdcl->getRegVar());
1075-
vISA_ASSERT(pointees, "expecting valid pointee list");
1076-
for (const auto &pointee : *pointees) {
1077-
auto &Uses =
1078-
VarRefs[pointee.var->getDeclare()->getRootDeclare()].second;
1079-
Uses.push_back(std::make_tuple(inst, bb));
1080-
}
1081-
}
10821060
}
10831061
}
10841062

visa/LoopAnalysis.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ SPDX-License-Identifier: MIT
1616
namespace vISA {
1717
class G4_BB;
1818
class FlowGraph;
19-
class PointsToAnalysis;
2019

2120
// Top level Analysis class that each analysis needs to inherit.
2221
// Each inherited class needs to implement their own reset() and
@@ -92,24 +91,19 @@ class PostDom : public Analysis {
9291
};
9392

9493
// Computes and stores direct references of variables.
95-
// Indirects references are computed only if PointsToAnalysis instance
96-
// is valid.
94+
// Indirects references are not computed here.
9795
class VarReferences : public Analysis {
9896
public:
9997
VarReferences(G4_Kernel &k, bool GRF = false, bool bounds = true,
100-
bool pseudoKills = false, PointsToAnalysis* p = nullptr)
98+
bool pseudoKills = false)
10199
: kernel(k), onlyGRF(GRF), needBounds(bounds),
102-
reportPseudoKill(pseudoKills), p2a(p) {}
100+
reportPseudoKill(pseudoKills) {}
103101

104102
// Defs -> vector[tuple<inst, bb, lb, rb>]
105103
// Uses -> vector[tuple<inst, bb>]
106-
// TODO: Store G4_DstRegRegion instead of G4_INST* in Defs,
107-
// G4_SrcRegResion instead of G4_INST* in Uses
108104
using Defs =
109105
std::vector<std::tuple<G4_INST *, G4_BB *, unsigned int, unsigned int>>;
110106
using Uses = std::vector<std::tuple<G4_INST *, G4_BB *>>;
111-
// Set to large enough number so its never a valid bound
112-
const unsigned int UnknownBound = 0xffff;
113107

114108
bool isUniqueDef(G4_Operand *dst);
115109
unsigned int getDefCount(G4_Declare *dcl);
@@ -126,7 +120,6 @@ class VarReferences : public Analysis {
126120
bool onlyGRF = false;
127121
bool needBounds = true;
128122
bool reportPseudoKill = false;
129-
PointsToAnalysis *p2a = nullptr;
130123

131124
void reset() override;
132125
void run() override;

0 commit comments

Comments
 (0)