Skip to content

Commit f36246e

Browse files
pratikasharsys_zuul
authored andcommitted
Implementation of VISA stack call ABI in generated code. Also update
VISA debug info as per ABI. Change-Id: I960549b920ec25ad5e73c2d15659e677a415b22e
1 parent 79e29f5 commit f36246e

File tree

9 files changed

+270
-131
lines changed

9 files changed

+270
-131
lines changed

visa/BuildIR.h

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,12 @@ class IR_Builder
372372
// function call related declares
373373
G4_Declare* be_sp = nullptr;
374374
G4_Declare* be_fp = nullptr;
375+
// Part FDE inst is the move that stores r125.[0-3] to a temp.
376+
// This is used to restore ret %ip, ret EM, and BE ptrs.
377+
G4_INST* savePartFDInst = nullptr;
378+
// FDE spill inst is first spill instruction that writes frame
379+
// descriptor to stack.
380+
G4_INST* FDSpillInst = nullptr;
375381
G4_Declare* tmpFCRet = nullptr;
376382

377383
unsigned short arg_size;
@@ -482,12 +488,23 @@ class IR_Builder
482488

483489
const USE_DEF_ALLOCATOR& getAllocator() const { return useDefAllocator; }
484490

485-
enum SubRegs_SP_FP
491+
// Following enum describes layout of r125 on entry to a function.
492+
// Ret_IP and Ret_EM may be altered due to callees. They'll be
493+
// restored right before fret.
494+
enum SubRegs_Stackcall
486495
{
487-
FE_SP = 0, // Can be either :ud or :uq
488-
FE_FP = 1, // Can be either :ud or :uq
489-
BE_SP = 6, // :ud
490-
BE_FP = 7 // :ud
496+
Ret_IP = 0, // :ud
497+
Ret_EM = 1, // :ud
498+
BE_SP = 2, // :ud
499+
BE_FP = 3, // :ud
500+
FE_FP = 2, // :uq
501+
FE_SP = 3, // :uq
502+
};
503+
504+
enum ArgRet_Stackcall
505+
{
506+
Arg = 26,
507+
Ret = 26
491508
};
492509

493510
// Getter/setter for be_sp and be_fp
@@ -496,7 +513,7 @@ class IR_Builder
496513
if (be_sp == NULL)
497514
{
498515
be_sp = createDeclareNoLookup("be_sp", G4_GRF, 1, 1, Type_UD);
499-
be_sp->getRegVar()->setPhyReg(phyregpool.getGreg(kernel.getFPSPGRF()), SubRegs_SP_FP::BE_SP);
516+
be_sp->getRegVar()->setPhyReg(phyregpool.getGreg(kernel.getFPSPGRF()), SubRegs_Stackcall::BE_SP);
500517
}
501518

502519
return be_sp;
@@ -507,12 +524,18 @@ class IR_Builder
507524
if (be_fp == NULL)
508525
{
509526
be_fp = createDeclareNoLookup("be_fp", G4_GRF, 1, 1, Type_UD);
510-
be_fp->getRegVar()->setPhyReg(phyregpool.getGreg(kernel.getFPSPGRF()), SubRegs_SP_FP::BE_FP);
527+
be_fp->getRegVar()->setPhyReg(phyregpool.getGreg(kernel.getFPSPGRF()), SubRegs_Stackcall::BE_FP);
511528
}
512529

513530
return be_fp;
514531
}
515532

533+
G4_INST* getPartFDSaveInst() const { return savePartFDInst; }
534+
void setPartFDSaveInst(G4_INST* i) { savePartFDInst = i; }
535+
536+
G4_INST* getFDSpillInst() const { return FDSpillInst; }
537+
void setFDSpillInst(G4_INST* i) { FDSpillInst = i; }
538+
516539
G4_Declare* getStackCallArg() const {
517540
return preDefVars.getPreDefinedVar(PreDefinedVarsInternal::ARG);
518541
}

visa/BuildIRImpl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -626,29 +626,29 @@ void IR_Builder::createPreDefinedVars()
626626
case PreDefinedVarsInternal::ARG:
627627
{
628628
dcl = createDeclareNoLookup(name, G4_INPUT, numEltPerGRF(Type_UD), 32, Type_UD);
629-
dcl->getRegVar()->setPhyReg(phyregpool.getGreg(28), 0);
629+
dcl->getRegVar()->setPhyReg(phyregpool.getGreg(ArgRet_Stackcall::Arg), 0);
630630
break;
631631
}
632632
case PreDefinedVarsInternal::RET:
633633
{
634634
dcl = createDeclareNoLookup(name, G4_GRF, numEltPerGRF(Type_UD), 12, Type_UD);
635-
dcl->getRegVar()->setPhyReg(phyregpool.getGreg(16), 0);
635+
dcl->getRegVar()->setPhyReg(phyregpool.getGreg(ArgRet_Stackcall::Ret), 0);
636636
dcl->setLiveOut();
637637
break;
638638
}
639639
case PreDefinedVarsInternal::FE_SP:
640640
{
641641
unsigned int startReg = kernel.getFPSPGRF();
642642
dcl = createDeclareNoLookup(name, G4_GRF, 1, 1, Type_UQ);
643-
dcl->getRegVar()->setPhyReg(phyregpool.getGreg(startReg), SubRegs_SP_FP::FE_SP);
643+
dcl->getRegVar()->setPhyReg(phyregpool.getGreg(startReg), SubRegs_Stackcall::FE_SP);
644644
break;
645645
}
646646
case PreDefinedVarsInternal::FE_FP:
647647
{
648648
// PREDEFINED_FE_FP
649649
unsigned int startReg = kernel.getFPSPGRF();
650650
dcl = createDeclareNoLookup(name, G4_GRF, 1, 1, Type_UQ);
651-
dcl->getRegVar()->setPhyReg(phyregpool.getGreg(startReg), SubRegs_SP_FP::FE_FP);
651+
dcl->getRegVar()->setPhyReg(phyregpool.getGreg(startReg), SubRegs_Stackcall::FE_FP);
652652
break;
653653
}
654654
case PreDefinedVarsInternal::HW_TID:

visa/DebugInfo.cpp

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,21 +1053,58 @@ void emitDataVarLiveInterval(VISAKernelImpl* visaKernel, LiveIntervalInfo* lrInf
10531053
}
10541054
}
10551055

1056+
template<class T>
1057+
void emitFrameDescriptorOffsetLiveInterval(LiveIntervalInfo* lrInfo, StackCall::FrameDescriptorOfsets memOffset, T& t)
1058+
{
1059+
// Used to emit fields of Frame Descriptor
1060+
// location = [start, end) @ BE_FP+offset
1061+
std::vector<std::pair<uint32_t, uint32_t>> lrs;
1062+
if (lrInfo)
1063+
lrInfo->getLiveIntervals(lrs);
1064+
else
1065+
return;
1066+
1067+
uint32_t start = 0, end = 0;
1068+
if (lrs.size() > 0)
1069+
{
1070+
start = lrs.front().first;
1071+
end = lrs.back().second;
1072+
}
1073+
1074+
std::sort(lrs.begin(), lrs.end(), [](std::pair<uint32_t, uint32_t>& a, std::pair<uint32_t, uint32_t>& b) { return a.first < b.first; });
1075+
1076+
emitDataUInt16(1, t);
1077+
1078+
emitDataUInt32(start, t);
1079+
emitDataUInt32(end, t);
1080+
1081+
emitDataUInt8((uint8_t)VARMAP_PREG_FILE_GRF, t);
1082+
1083+
emitDataUInt8((uint8_t)VARMAP_PREG_FILE_MEMORY, t);
1084+
1085+
emitDataUInt32((uint32_t)memOffset, t);
1086+
}
1087+
10561088
void populateUniqueSubs(G4_Kernel* kernel, std::unordered_map<G4_BB*, bool>& uniqueSubs)
10571089
{
10581090
// Traverse kernel and populate all unique subs.
10591091
// Iterating over all BBs of kernel visits all
10601092
// subroutine call sites.
1093+
auto isStackObj = kernel->fg.getHasStackCalls() || kernel->fg.getIsStackCallFunc();
10611094
for (auto bb : kernel->fg)
10621095
{
10631096
if (&bb->getParent() != &kernel->fg)
10641097
continue;
10651098

1066-
if (bb->isEndWithCall() &&
1067-
!kernel->getKernelDebugInfo()->isFcallWithSaveRestore(bb))
1099+
if (bb->isEndWithCall())
10681100
{
1069-
// This is a subroutine call
1070-
uniqueSubs[bb->Succs.front()] = false;
1101+
if (!isStackObj || // definitely a subroutine since kernel has no stack calls
1102+
(isStackObj && // a subroutine iff call dst != pre-defined reg as per ABI
1103+
bb->back()->getDst()->getTopDcl()->getRegVar()->getPhyReg()->asGreg()->getRegNum() != kernel->getFPSPGRF()))
1104+
{
1105+
// This is a subroutine call
1106+
uniqueSubs[bb->Succs.front()] = false;
1107+
}
10711108
}
10721109
}
10731110
}
@@ -1205,16 +1242,16 @@ void SaveRestoreManager::sieveInstructions(CallerOrCallee c)
12051242
// Remove temp movs emitted for send header
12061243
// creation since they are not technically
12071244
// caller save
1208-
if (entry.first < CALLEE_SAVE_START &&
1209-
entry.first >= CALLER_SAVE_START &&
1245+
if (entry.first < visaKernel->getKernel()->calleeSaveStart() &&
1246+
entry.first >= 0 &&
12101247
entry.second.first == SaveRestoreInfo::RegOrMem::MemOffBEFP)
12111248
{
12121249
removeEntry = false;
12131250
}
12141251
}
12151252
else if (c == CallerOrCallee::Callee)
12161253
{
1217-
if (entry.first >= CALLEE_SAVE_START &&
1254+
if (entry.first >= visaKernel->getKernel()->calleeSaveStart() &&
12181255
entry.second.first == SaveRestoreInfo::RegOrMem::MemOffBEFP)
12191256
{
12201257
removeEntry = false;
@@ -1408,7 +1445,7 @@ void emitDataCallFrameInfo(VISAKernelImpl* visaKernel, T& t)
14081445
if (befpLIInfo)
14091446
{
14101447
emitDataUInt8((uint8_t)1, t);
1411-
uint32_t idx = kernel->getKernelDebugInfo()->getVarIndex(befpDcl);
1448+
uint32_t idx = kernel->getKernelDebugInfo()->getVarIndex(kernel->fg.framePtrDcl);
14121449
emitDataVarLiveInterval(visaKernel, befpLIInfo, idx, sizeof(uint32_t), t);
14131450
}
14141451
else
@@ -1428,8 +1465,8 @@ void emitDataCallFrameInfo(VISAKernelImpl* visaKernel, T& t)
14281465
if (callerfpLIInfo)
14291466
{
14301467
emitDataUInt8((uint8_t)1, t);
1431-
uint32_t idx = kernel->getKernelDebugInfo()->getVarIndex(callerfpdcl);
1432-
emitDataVarLiveInterval(visaKernel, callerfpLIInfo, idx, sizeof(uint32_t), t);
1468+
// Caller's be_fp is stored in frame descriptor
1469+
emitFrameDescriptorOffsetLiveInterval(callerfpLIInfo, StackCall::FrameDescriptorOfsets::BE_FP, t);
14331470
}
14341471
else
14351472
{
@@ -1448,8 +1485,7 @@ void emitDataCallFrameInfo(VISAKernelImpl* visaKernel, T& t)
14481485
if (fretVarLIInfo)
14491486
{
14501487
emitDataUInt8((uint8_t)1, t);
1451-
uint32_t idx = kernel->getKernelDebugInfo()->getVarIndex(fretVar);
1452-
emitDataVarLiveInterval(visaKernel, fretVarLIInfo, idx, sizeof(uint32_t), t);
1488+
emitFrameDescriptorOffsetLiveInterval(fretVarLIInfo, StackCall::FrameDescriptorOfsets::Ret_IP, t);
14531489
}
14541490
else
14551491
{
@@ -1934,6 +1970,29 @@ void KernelDebugInfo::computeDebugInfo(std::list<G4_BB*>& stackCallEntryBBs)
19341970
{
19351971
updateCallStackLiveIntervals();
19361972
}
1973+
else
1974+
{
1975+
updateCallStackMain();
1976+
}
1977+
}
1978+
1979+
void KernelDebugInfo::updateCallStackMain()
1980+
{
1981+
if (!getKernel().fg.getHasStackCalls())
1982+
return;
1983+
1984+
// Set live-interval for BE_FP
1985+
auto befp = getBEFP();
1986+
if (befp)
1987+
{
1988+
uint32_t start = 0;
1989+
if (getBEFPSetupInst())
1990+
{
1991+
start = (uint32_t)getBEFPSetupInst()->getGenOffset() +
1992+
(uint32_t)getBinInstSize(getBEFPSetupInst());
1993+
}
1994+
updateDebugInfo(getKernel(), befp, start, mapCISAIndexGenOffset.back().second);
1995+
}
19371996
}
19381997

19391998
void KernelDebugInfo::updateCallStackLiveIntervals()
@@ -1964,24 +2023,30 @@ void KernelDebugInfo::updateCallStackLiveIntervals()
19642023
{
19652024
reloc_offset = (reloc_offset == 0) ?
19662025
(uint32_t)insts->getGenOffset() : reloc_offset;
1967-
}
1968-
1969-
if ((insts->isReturn() || insts->opcode() == G4_jmpi) &&
1970-
insts->getSrc(0)->asSrcRegRegion()->getBase()->asRegVar()->getDeclare()->getRootDeclare()
1971-
== fretVar)
1972-
{
1973-
end = (uint32_t)insts->getGenOffset();
19742026
break;
19752027
}
19762028
}
1977-
if (end > 0)
1978-
{
2029+
if (reloc_offset > 0)
19792030
break;
1980-
}
2031+
}
2032+
2033+
uint32_t start = 0;
2034+
if (getBEFPSetupInst())
2035+
{
2036+
// Frame descriptor can be addressed once once BE_FP is defined
2037+
start = (uint32_t)getBEFPSetupInst()->getGenOffset() +
2038+
getBinInstSize(getBEFPSetupInst());
2039+
}
2040+
2041+
if (getCallerBEFPRestoreInst())
2042+
{
2043+
end = (uint32_t)getCallerBEFPRestoreInst()->getGenOffset();
19812044
}
19822045

19832046
MUST_BE_TRUE(end >= reloc_offset, "Failed to update live-interval for retval");
1984-
for (uint32_t i = 0; i <= end - reloc_offset; i++)
2047+
MUST_BE_TRUE(start >= reloc_offset, "Failed to update start for retval");
2048+
MUST_BE_TRUE(end >= start, "end less then start for retval");
2049+
for (uint32_t i = start - reloc_offset; i <= end - reloc_offset; i++)
19852050
{
19862051
updateDebugInfo(*kernel, fretVar, i);
19872052
}

visa/DebugInfo.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3434
#include "GraphColor.h"
3535
#include <unordered_map>
3636

37-
#define CALLER_SAVE_START 1
38-
#define CALLEE_SAVE_START 60
3937
namespace vISA
4038
{
4139
class G4_Declare;
@@ -279,6 +277,7 @@ class KernelDebugInfo
279277
void generateCISAByteOffsetFromOffset();
280278
void updateRelocOffset();
281279
void updateCallStackLiveIntervals();
280+
void updateCallStackMain();
282281
void generateGenISAToVISAIndex();
283282

284283
void computeDebugInfo(std::list<G4_BB*>& stackCallEntryBBs);

0 commit comments

Comments
 (0)