Skip to content

Commit 4333146

Browse files
committed
[NFC][AsmPrinter] Use std::visit in constructVariableDIEImpl
This potentially has a slightly positive performance impact, as std::visit can be implemented as a `switch`-like jump rather than a series of `if`s. More importantly, the reader can be confident is no overlap between the cases. Differential Revision: https://reviews.llvm.org/D158678
1 parent 35e621f commit 4333146

File tree

2 files changed

+202
-189
lines changed

2 files changed

+202
-189
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 191 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -771,192 +771,197 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
771771
}
772772

773773
// Add variable address.
774-
775-
if (auto *Multi = std::get_if<Loc::Multi>(&DV)) {
776-
addLocationList(*VariableDie, dwarf::DW_AT_location,
777-
Multi->getDebugLocListIndex());
778-
auto TagOffset = Multi->getDebugLocListTagOffset();
779-
if (TagOffset)
780-
addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
781-
*TagOffset);
782-
return VariableDie;
783-
}
784-
785-
// Check if variable has a single location description.
786-
if (const auto *Single = std::get_if<Loc::Single>(&DV)) {
787-
const DbgValueLoc *DVal = &Single->getValueLoc();
788-
if (!DVal->isVariadic()) {
789-
const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
790-
if (Entry->isLocation()) {
791-
addVariableAddress(DV, *VariableDie, Entry->getLoc());
792-
} else if (Entry->isInt()) {
793-
auto *Expr = Single->getExpr();
794-
if (Expr && Expr->getNumElements()) {
795-
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
796-
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
797-
// If there is an expression, emit raw unsigned bytes.
798-
DwarfExpr.addFragmentOffset(Expr);
799-
DwarfExpr.addUnsignedConstant(Entry->getInt());
800-
DwarfExpr.addExpression(Expr);
801-
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
802-
if (DwarfExpr.TagOffset)
803-
addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
804-
dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
805-
} else
806-
addConstantValue(*VariableDie, Entry->getInt(), DV.getType());
807-
} else if (Entry->isConstantFP()) {
808-
addConstantFPValue(*VariableDie, Entry->getConstantFP());
809-
} else if (Entry->isConstantInt()) {
810-
addConstantValue(*VariableDie, Entry->getConstantInt(), DV.getType());
811-
} else if (Entry->isTargetIndexLocation()) {
812-
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
813-
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
814-
const DIBasicType *BT = dyn_cast<DIBasicType>(
815-
static_cast<const Metadata *>(DV.getVariable()->getType()));
816-
DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
817-
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
818-
}
819-
return VariableDie;
820-
}
821-
// If any of the location entries are registers with the value 0, then the
822-
// location is undefined.
823-
if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {
824-
return Entry.isLocation() && !Entry.getLoc().getReg();
825-
}))
826-
return VariableDie;
827-
const DIExpression *Expr = Single->getExpr();
828-
assert(Expr && "Variadic Debug Value must have an Expression.");
829-
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
830-
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
831-
DwarfExpr.addFragmentOffset(Expr);
832-
DIExpressionCursor Cursor(Expr);
833-
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
834-
835-
auto AddEntry = [&](const DbgValueLocEntry &Entry,
836-
DIExpressionCursor &Cursor) {
837-
if (Entry.isLocation()) {
838-
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
839-
Entry.getLoc().getReg()))
840-
return false;
841-
} else if (Entry.isInt()) {
842-
// If there is an expression, emit raw unsigned bytes.
843-
DwarfExpr.addUnsignedConstant(Entry.getInt());
844-
} else if (Entry.isConstantFP()) {
845-
// DwarfExpression does not support arguments wider than 64 bits
846-
// (see PR52584).
847-
// TODO: Consider chunking expressions containing overly wide
848-
// arguments into separate pointer-sized fragment expressions.
849-
APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
850-
if (RawBytes.getBitWidth() > 64)
851-
return false;
852-
DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
853-
} else if (Entry.isConstantInt()) {
854-
APInt RawBytes = Entry.getConstantInt()->getValue();
855-
if (RawBytes.getBitWidth() > 64)
856-
return false;
857-
DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
858-
} else if (Entry.isTargetIndexLocation()) {
859-
TargetIndexLocation Loc = Entry.getTargetIndexLocation();
860-
// TODO TargetIndexLocation is a target-independent. Currently only the
861-
// WebAssembly-specific encoding is supported.
862-
assert(Asm->TM.getTargetTriple().isWasm());
863-
DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
864-
} else {
865-
llvm_unreachable("Unsupported Entry type.");
866-
}
867-
return true;
868-
};
869-
870-
if (!DwarfExpr.addExpression(
871-
std::move(Cursor),
872-
[&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
873-
return AddEntry(DVal->getLocEntries()[Idx], Cursor);
874-
}))
875-
return VariableDie;
876-
877-
// Now attach the location information to the DIE.
878-
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
879-
if (DwarfExpr.TagOffset)
880-
addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
881-
*DwarfExpr.TagOffset);
882-
883-
return VariableDie;
884-
}
885-
886-
if (auto *EntryValue = std::get_if<Loc::EntryValue>(&DV)) {
887-
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
888-
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
889-
// Emit each expression as: EntryValue(Register) <other ops> <Fragment>.
890-
for (auto [Register, Expr] : EntryValue->EntryValues) {
891-
DwarfExpr.addFragmentOffset(&Expr);
892-
DIExpressionCursor Cursor(Expr.getElements());
893-
DwarfExpr.beginEntryValueExpression(Cursor);
894-
DwarfExpr.addMachineRegExpression(
895-
*Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register);
896-
DwarfExpr.addExpression(std::move(Cursor));
897-
}
898-
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
899-
return VariableDie;
900-
}
901-
902-
// .. else use frame index.
903-
if (!DV.holds<Loc::MMI>())
904-
return VariableDie;
905-
906-
std::optional<unsigned> NVPTXAddressSpace;
907-
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
908-
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
909-
for (const auto &Fragment : DV.get<Loc::MMI>().getFrameIndexExprs()) {
910-
Register FrameReg;
911-
const DIExpression *Expr = Fragment.Expr;
912-
const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
913-
StackOffset Offset =
914-
TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
915-
DwarfExpr.addFragmentOffset(Expr);
916-
917-
auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();
918-
SmallVector<uint64_t, 8> Ops;
919-
TRI->getOffsetOpcodes(Offset, Ops);
920-
921-
// According to
922-
// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
923-
// cuda-gdb requires DW_AT_address_class for all variables to be able to
924-
// correctly interpret address space of the variable address.
925-
// Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
926-
// sequence for the NVPTX + gdb target.
927-
unsigned LocalNVPTXAddressSpace;
928-
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
929-
const DIExpression *NewExpr =
930-
DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
931-
if (NewExpr != Expr) {
932-
Expr = NewExpr;
933-
NVPTXAddressSpace = LocalNVPTXAddressSpace;
934-
}
935-
}
936-
if (Expr)
937-
Ops.append(Expr->elements_begin(), Expr->elements_end());
938-
DIExpressionCursor Cursor(Ops);
939-
DwarfExpr.setMemoryLocationKind();
940-
if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())
941-
addOpAddress(*Loc, FrameSymbol);
942-
else
943-
DwarfExpr.addMachineRegExpression(
944-
*Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
945-
DwarfExpr.addExpression(std::move(Cursor));
946-
}
947-
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
948-
// According to
949-
// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
950-
// cuda-gdb requires DW_AT_address_class for all variables to be able to
951-
// correctly interpret address space of the variable address.
952-
const unsigned NVPTX_ADDR_local_space = 6;
953-
addUInt(*VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
954-
NVPTXAddressSpace.value_or(NVPTX_ADDR_local_space));
955-
}
956-
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
957-
if (DwarfExpr.TagOffset)
958-
addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
959-
*DwarfExpr.TagOffset);
774+
std::visit(
775+
makeVisitor(
776+
[=, &DV](const Loc::Single &Single) {
777+
const DbgValueLoc *DVal = &Single.getValueLoc();
778+
if (!DVal->isVariadic()) {
779+
const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
780+
if (Entry->isLocation()) {
781+
addVariableAddress(DV, *VariableDie, Entry->getLoc());
782+
} else if (Entry->isInt()) {
783+
auto *Expr = Single.getExpr();
784+
if (Expr && Expr->getNumElements()) {
785+
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
786+
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
787+
// If there is an expression, emit raw unsigned bytes.
788+
DwarfExpr.addFragmentOffset(Expr);
789+
DwarfExpr.addUnsignedConstant(Entry->getInt());
790+
DwarfExpr.addExpression(Expr);
791+
addBlock(*VariableDie, dwarf::DW_AT_location,
792+
DwarfExpr.finalize());
793+
if (DwarfExpr.TagOffset)
794+
addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
795+
dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
796+
} else
797+
addConstantValue(*VariableDie, Entry->getInt(), DV.getType());
798+
} else if (Entry->isConstantFP()) {
799+
addConstantFPValue(*VariableDie, Entry->getConstantFP());
800+
} else if (Entry->isConstantInt()) {
801+
addConstantValue(*VariableDie, Entry->getConstantInt(),
802+
DV.getType());
803+
} else if (Entry->isTargetIndexLocation()) {
804+
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
805+
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
806+
const DIBasicType *BT = dyn_cast<DIBasicType>(
807+
static_cast<const Metadata *>(DV.getVariable()->getType()));
808+
DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
809+
addBlock(*VariableDie, dwarf::DW_AT_location,
810+
DwarfExpr.finalize());
811+
}
812+
return;
813+
}
814+
// If any of the location entries are registers with the value 0,
815+
// then the location is undefined.
816+
if (any_of(DVal->getLocEntries(),
817+
[](const DbgValueLocEntry &Entry) {
818+
return Entry.isLocation() && !Entry.getLoc().getReg();
819+
}))
820+
return;
821+
const DIExpression *Expr = Single.getExpr();
822+
assert(Expr && "Variadic Debug Value must have an Expression.");
823+
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
824+
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
825+
DwarfExpr.addFragmentOffset(Expr);
826+
DIExpressionCursor Cursor(Expr);
827+
const TargetRegisterInfo &TRI =
828+
*Asm->MF->getSubtarget().getRegisterInfo();
829+
830+
auto AddEntry = [&](const DbgValueLocEntry &Entry,
831+
DIExpressionCursor &Cursor) {
832+
if (Entry.isLocation()) {
833+
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
834+
Entry.getLoc().getReg()))
835+
return false;
836+
} else if (Entry.isInt()) {
837+
// If there is an expression, emit raw unsigned bytes.
838+
DwarfExpr.addUnsignedConstant(Entry.getInt());
839+
} else if (Entry.isConstantFP()) {
840+
// DwarfExpression does not support arguments wider than 64 bits
841+
// (see PR52584).
842+
// TODO: Consider chunking expressions containing overly wide
843+
// arguments into separate pointer-sized fragment expressions.
844+
APInt RawBytes =
845+
Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
846+
if (RawBytes.getBitWidth() > 64)
847+
return false;
848+
DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
849+
} else if (Entry.isConstantInt()) {
850+
APInt RawBytes = Entry.getConstantInt()->getValue();
851+
if (RawBytes.getBitWidth() > 64)
852+
return false;
853+
DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());
854+
} else if (Entry.isTargetIndexLocation()) {
855+
TargetIndexLocation Loc = Entry.getTargetIndexLocation();
856+
// TODO TargetIndexLocation is a target-independent. Currently
857+
// only the WebAssembly-specific encoding is supported.
858+
assert(Asm->TM.getTargetTriple().isWasm());
859+
DwarfExpr.addWasmLocation(Loc.Index,
860+
static_cast<uint64_t>(Loc.Offset));
861+
} else {
862+
llvm_unreachable("Unsupported Entry type.");
863+
}
864+
return true;
865+
};
866+
867+
if (!DwarfExpr.addExpression(
868+
std::move(Cursor),
869+
[&](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
870+
return AddEntry(DVal->getLocEntries()[Idx], Cursor);
871+
}))
872+
return;
873+
874+
// Now attach the location information to the DIE.
875+
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
876+
if (DwarfExpr.TagOffset)
877+
addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
878+
dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
879+
},
880+
[=](const Loc::Multi &Multi) {
881+
addLocationList(*VariableDie, dwarf::DW_AT_location,
882+
Multi.getDebugLocListIndex());
883+
auto TagOffset = Multi.getDebugLocListTagOffset();
884+
if (TagOffset)
885+
addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
886+
dwarf::DW_FORM_data1, *TagOffset);
887+
},
888+
[=](const Loc::MMI &MMI) {
889+
std::optional<unsigned> NVPTXAddressSpace;
890+
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
891+
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
892+
for (const auto &Fragment : MMI.getFrameIndexExprs()) {
893+
Register FrameReg;
894+
const DIExpression *Expr = Fragment.Expr;
895+
const TargetFrameLowering *TFI =
896+
Asm->MF->getSubtarget().getFrameLowering();
897+
StackOffset Offset =
898+
TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
899+
DwarfExpr.addFragmentOffset(Expr);
900+
901+
auto *TRI = Asm->MF->getSubtarget().getRegisterInfo();
902+
SmallVector<uint64_t, 8> Ops;
903+
TRI->getOffsetOpcodes(Offset, Ops);
904+
905+
// According to
906+
// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
907+
// cuda-gdb requires DW_AT_address_class for all variables to be
908+
// able to correctly interpret address space of the variable
909+
// address. Decode DW_OP_constu <DWARF Address Space> DW_OP_swap
910+
// DW_OP_xderef sequence for the NVPTX + gdb target.
911+
unsigned LocalNVPTXAddressSpace;
912+
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
913+
const DIExpression *NewExpr = DIExpression::extractAddressClass(
914+
Expr, LocalNVPTXAddressSpace);
915+
if (NewExpr != Expr) {
916+
Expr = NewExpr;
917+
NVPTXAddressSpace = LocalNVPTXAddressSpace;
918+
}
919+
}
920+
if (Expr)
921+
Ops.append(Expr->elements_begin(), Expr->elements_end());
922+
DIExpressionCursor Cursor(Ops);
923+
DwarfExpr.setMemoryLocationKind();
924+
if (const MCSymbol *FrameSymbol = Asm->getFunctionFrameSymbol())
925+
addOpAddress(*Loc, FrameSymbol);
926+
else
927+
DwarfExpr.addMachineRegExpression(
928+
*Asm->MF->getSubtarget().getRegisterInfo(), Cursor,
929+
FrameReg);
930+
DwarfExpr.addExpression(std::move(Cursor));
931+
}
932+
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
933+
// According to
934+
// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
935+
// cuda-gdb requires DW_AT_address_class for all variables to be
936+
// able to correctly interpret address space of the variable
937+
// address.
938+
const unsigned NVPTX_ADDR_local_space = 6;
939+
addUInt(*VariableDie, dwarf::DW_AT_address_class,
940+
dwarf::DW_FORM_data1,
941+
NVPTXAddressSpace.value_or(NVPTX_ADDR_local_space));
942+
}
943+
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
944+
if (DwarfExpr.TagOffset)
945+
addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
946+
dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
947+
},
948+
[=](const Loc::EntryValue &EntryValue) {
949+
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
950+
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
951+
// Emit each expression as: EntryValue(Register) <other ops>
952+
// <Fragment>.
953+
for (auto [Register, Expr] : EntryValue.EntryValues) {
954+
DwarfExpr.addFragmentOffset(&Expr);
955+
DIExpressionCursor Cursor(Expr.getElements());
956+
DwarfExpr.beginEntryValueExpression(Cursor);
957+
DwarfExpr.addMachineRegExpression(
958+
*Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register);
959+
DwarfExpr.addExpression(std::move(Cursor));
960+
}
961+
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
962+
},
963+
[](const std::monostate &) {}),
964+
DV.asVariant());
960965

961966
return VariableDie;
962967
}

0 commit comments

Comments
 (0)