Changeset View
Changeset View
Standalone View
Standalone View
lib/CodeGen/StackMaps.cpp
Show First 20 Lines • Show All 325 Lines • ▼ Show 20 Lines | void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID, | ||||
// entry. | // entry. | ||||
const MCExpr *CSOffsetExpr = MCBinaryExpr::createSub( | const MCExpr *CSOffsetExpr = MCBinaryExpr::createSub( | ||||
MCSymbolRefExpr::create(MILabel, OutContext), | MCSymbolRefExpr::create(MILabel, OutContext), | ||||
MCSymbolRefExpr::create(AP.CurrentFnSymForSize, OutContext), OutContext); | MCSymbolRefExpr::create(AP.CurrentFnSymForSize, OutContext), OutContext); | ||||
CSInfos.emplace_back(CSOffsetExpr, ID, std::move(Locations), | CSInfos.emplace_back(CSOffsetExpr, ID, std::move(Locations), | ||||
std::move(LiveOuts)); | std::move(LiveOuts)); | ||||
// Record the stack size of the current function. | // Record the stack size of the current function and update callsite count. | ||||
const MachineFrameInfo &MFI = AP.MF->getFrameInfo(); | const MachineFrameInfo &MFI = AP.MF->getFrameInfo(); | ||||
const TargetRegisterInfo *RegInfo = AP.MF->getSubtarget().getRegisterInfo(); | const TargetRegisterInfo *RegInfo = AP.MF->getSubtarget().getRegisterInfo(); | ||||
bool HasDynamicFrameSize = | bool HasDynamicFrameSize = | ||||
MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(*(AP.MF)); | MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(*(AP.MF)); | ||||
FnStackSize[AP.CurrentFnSym] = | uint64_t FrameSize = HasDynamicFrameSize ? UINT64_MAX : MFI.getStackSize(); | ||||
HasDynamicFrameSize ? UINT64_MAX : MFI.getStackSize(); | |||||
if (FnInfos.count(AP.CurrentFnSym)) { | |||||
FunctionInfo ¤t = FnInfos[AP.CurrentFnSym]; | |||||
sanjoy: Indent looks off? Use `clang-format`. | |||||
sanjoyUnsubmitted s/current/Current/ in keeping with LLVM coding style. sanjoy: s/`current`/`Current`/ in keeping with LLVM coding style. | |||||
current.StackSize = FrameSize; | |||||
sanjoyUnsubmitted Why do you need to assign StackSize again? Can't this whole block be: auto CurrentIt = FnInfos.find(AP.CurrentFnSym); if (CurrentIt != FnInfos.end() CurrentIt->second.RecordCount++; else FnInfos.insert(...); ? sanjoy: Why do you need to assign `StackSize` again?
Can't this whole block be:
```
auto CurrentIt =… | |||||
kavonAuthorUnsubmitted Not Done ReplyInline ActionsI only reassign StackSize because that's what the previous implementation did, and I didn't want to mess with a good thing ;) I have now changed the block to match your suggestion. kavon: I only reassign StackSize because that's what the previous implementation did, and I didn't… | |||||
current.RecordCount = current.RecordCount + 1; | |||||
} else { | |||||
Not Done ReplyInline ActionsI think this can be FnInfos.insert({AP.CurrentFnSym, FunctionInfo(FrameSize)}); sanjoy: I think this can be `FnInfos.insert({AP.CurrentFnSym, FunctionInfo(FrameSize)});`
| |||||
FnInfos[AP.CurrentFnSym] = FunctionInfo(FrameSize); | |||||
} | |||||
} | } | ||||
void StackMaps::recordStackMap(const MachineInstr &MI) { | void StackMaps::recordStackMap(const MachineInstr &MI) { | ||||
assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap"); | assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap"); | ||||
int64_t ID = MI.getOperand(0).getImm(); | int64_t ID = MI.getOperand(0).getImm(); | ||||
recordStackMapOpers(MI, ID, std::next(MI.operands_begin(), 2), | recordStackMapOpers(MI, ID, std::next(MI.operands_begin(), 2), | ||||
MI.operands_end()); | MI.operands_end()); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
/// uint32 : NumRecords | /// uint32 : NumRecords | ||||
void StackMaps::emitStackmapHeader(MCStreamer &OS) { | void StackMaps::emitStackmapHeader(MCStreamer &OS) { | ||||
// Header. | // Header. | ||||
OS.EmitIntValue(StackMapVersion, 1); // Version. | OS.EmitIntValue(StackMapVersion, 1); // Version. | ||||
OS.EmitIntValue(0, 1); // Reserved. | OS.EmitIntValue(0, 1); // Reserved. | ||||
OS.EmitIntValue(0, 2); // Reserved. | OS.EmitIntValue(0, 2); // Reserved. | ||||
// Num functions. | // Num functions. | ||||
DEBUG(dbgs() << WSMP << "#functions = " << FnStackSize.size() << '\n'); | DEBUG(dbgs() << WSMP << "#functions = " << FnInfos.size() << '\n'); | ||||
OS.EmitIntValue(FnStackSize.size(), 4); | OS.EmitIntValue(FnInfos.size(), 4); | ||||
// Num constants. | // Num constants. | ||||
DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n'); | DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n'); | ||||
OS.EmitIntValue(ConstPool.size(), 4); | OS.EmitIntValue(ConstPool.size(), 4); | ||||
// Num callsites. | // Num callsites. | ||||
DEBUG(dbgs() << WSMP << "#callsites = " << CSInfos.size() << '\n'); | DEBUG(dbgs() << WSMP << "#callsites = " << CSInfos.size() << '\n'); | ||||
OS.EmitIntValue(CSInfos.size(), 4); | OS.EmitIntValue(CSInfos.size(), 4); | ||||
} | } | ||||
/// Emit the function frame record for each function. | /// Emit the function frame record for each function. | ||||
/// | /// | ||||
/// StkSizeRecord[NumFunctions] { | /// StkSizeRecord[NumFunctions] { | ||||
/// uint64 : Function Address | /// uint64 : Function Address | ||||
/// uint64 : Stack Size | /// uint64 : Stack Size | ||||
/// uint64 : Record Count | |||||
/// } | /// } | ||||
void StackMaps::emitFunctionFrameRecords(MCStreamer &OS) { | void StackMaps::emitFunctionFrameRecords(MCStreamer &OS) { | ||||
// Function Frame records. | // Function Frame records. | ||||
DEBUG(dbgs() << WSMP << "functions:\n"); | DEBUG(dbgs() << WSMP << "functions:\n"); | ||||
for (auto const &FR : FnStackSize) { | for (auto const &FR : FnInfos) { | ||||
DEBUG(dbgs() << WSMP << "function addr: " << FR.first | DEBUG(dbgs() << WSMP << "function addr: " << FR.first | ||||
<< " frame size: " << FR.second); | << " frame size: " << FR.second.StackSize | ||||
<< " callsite count: " << FR.second.RecordCount << '\n'); | |||||
OS.EmitSymbolValue(FR.first, 8); | OS.EmitSymbolValue(FR.first, 8); | ||||
OS.EmitIntValue(FR.second, 8); | OS.EmitIntValue(FR.second.StackSize, 8); | ||||
OS.EmitIntValue(FR.second.RecordCount, 8); | |||||
} | } | ||||
} | } | ||||
/// Emit the constant pool. | /// Emit the constant pool. | ||||
/// | /// | ||||
/// int64 : Constants[NumConstants] | /// int64 : Constants[NumConstants] | ||||
void StackMaps::emitConstantPoolEntries(MCStreamer &OS) { | void StackMaps::emitConstantPoolEntries(MCStreamer &OS) { | ||||
// Constant pool entries. | // Constant pool entries. | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/// Serialize the stackmap data. | /// Serialize the stackmap data. | ||||
void StackMaps::serializeToStackMapSection() { | void StackMaps::serializeToStackMapSection() { | ||||
(void)WSMP; | (void)WSMP; | ||||
// Bail out if there's no stack map data. | // Bail out if there's no stack map data. | ||||
assert((!CSInfos.empty() || ConstPool.empty()) && | assert((!CSInfos.empty() || ConstPool.empty()) && | ||||
"Expected empty constant pool too!"); | "Expected empty constant pool too!"); | ||||
assert((!CSInfos.empty() || FnStackSize.empty()) && | assert((!CSInfos.empty() || FnInfos.empty()) && | ||||
Perhaps call FnInfo FnInfos instead (to go with CSInfos)? sanjoy: Perhaps call `FnInfo` `FnInfos` instead (to go with `CSInfos`)? | |||||
"Expected empty function record too!"); | "Expected empty function record too!"); | ||||
if (CSInfos.empty()) | if (CSInfos.empty()) | ||||
return; | return; | ||||
MCContext &OutContext = AP.OutStreamer->getContext(); | MCContext &OutContext = AP.OutStreamer->getContext(); | ||||
MCStreamer &OS = *AP.OutStreamer; | MCStreamer &OS = *AP.OutStreamer; | ||||
// Create the section. | // Create the section. | ||||
Show All 19 Lines |
Indent looks off? Use clang-format.