1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2023 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#include "DwarfExpression.hpp"
#include <optional>
using namespace IGC;
void DwarfExpression::emitConstu(uint64_t Value) {
if (Value < 32)
emitOp(static_cast<uint8_t>(dwarf::DW_OP_lit0 + Value));
else if (Value == std::numeric_limits<uint64_t>::max()) {
// Only do this for 64-bit values as the DWARF expression stack uses
// target-address-size values.
emitOp(dwarf::DW_OP_lit0);
emitOp(dwarf::DW_OP_not);
} else {
emitOp(dwarf::DW_OP_constu);
emitUnsigned(Value);
}
}
bool DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {
// Entry values can currently only cover the initial register location,
// and not any other parts of the following DWARF expression.
// assert(!IsEmittingEntryValue && "Can't emit entry value around
// expression");
std::optional<DIExpression::ExprOperand> PrevConvertOp = std::nullopt;
while (ExprCursor) {
auto Op = ExprCursor.take();
uint64_t OpNum = Op->getOp();
// if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
// emitOp(OpNum);
// continue;
// } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
// addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0));
// continue;
// }
switch (OpNum) {
// case dwarf::DW_OP_LLVM_arg:
// if (!InsertArg(Op->getArg(0), ExprCursor)) {
// LocationKind = Unknown;
// return false;
// }
// break;
// case dwarf::DW_OP_LLVM_fragment: {
// unsigned SizeInBits = Op->getArg(1);
// unsigned FragmentOffset = Op->getArg(0);
// // The fragment offset must have already been adjusted by emitting an
// // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
// // location.
// assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
// assert(SizeInBits >= OffsetInBits - FragmentOffset && "size
// underflow");
// // If addMachineReg already emitted DW_OP_piece operations to represent
// // a super-register by splicing together sub-registers, subtract the
// size
// // of the pieces that was already emitted.
// SizeInBits -= OffsetInBits - FragmentOffset;
// // If addMachineReg requested a DW_OP_bit_piece to stencil out a
// // sub-register that is smaller than the current fragment's size, use
// it. if (SubRegisterSizeInBits)
// SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
// // Emit a DW_OP_stack_value for implicit location descriptions.
// if (isImplicitLocation())
// addStackValue();
// // Emit the DW_OP_piece.
// addOpPiece(SizeInBits, SubRegisterOffsetInBits);
// setSubRegisterPiece(0, 0);
// // Reset the location description kind.
// LocationKind = Unknown;
// return true;
//}
case dwarf::DW_OP_plus_uconst:
// assert(!isRegisterLocation());
emitOp(dwarf::DW_OP_plus_uconst);
emitUnsigned(Op->getArg(0));
break;
case dwarf::DW_OP_plus:
case dwarf::DW_OP_minus:
case dwarf::DW_OP_mul:
case dwarf::DW_OP_div:
case dwarf::DW_OP_mod:
case dwarf::DW_OP_or:
case dwarf::DW_OP_and:
case dwarf::DW_OP_xor:
case dwarf::DW_OP_shl:
case dwarf::DW_OP_shr:
case dwarf::DW_OP_shra:
case dwarf::DW_OP_lit0:
case dwarf::DW_OP_not:
case dwarf::DW_OP_dup:
case dwarf::DW_OP_push_object_address:
case dwarf::DW_OP_over:
emitOp(static_cast<uint8_t>(OpNum));
break;
case dwarf::DW_OP_deref:
// assert(!isRegisterLocation());
// if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor))
// // Turning this into a memory location description makes the deref
// // implicit.
// LocationKind = Memory;
// else
emitOp(dwarf::DW_OP_deref);
break;
case dwarf::DW_OP_constu:
// assert(!isRegisterLocation());
emitConstu(Op->getArg(0));
break;
case dwarf::DW_OP_consts:
// assert(!isRegisterLocation());
emitOp(dwarf::DW_OP_consts);
emitSigned(Op->getArg(0));
break;
// case dwarf::DW_OP_LLVM_convert: {
// unsigned BitSize = Op->getArg(0);
// dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
// if (DwarfVersion >= 5 && CU.getDwarfDebug().useOpConvert()) {
// emitOp(dwarf::DW_OP_convert);
// // If targeting a location-list; simply emit the index into the raw
// // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
// // fitted with means to extract it later.
// // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef
// // (containing the index and a resolve mechanism during emit) into
// the
// // DIE value list.
// emitBaseTypeRef(getOrCreateBaseType(BitSize, Encoding));
// } else {
// if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {
// if (Encoding == dwarf::DW_ATE_signed)
// emitLegacySExt(PrevConvertOp->getArg(0));
// else if (Encoding == dwarf::DW_ATE_unsigned)
// emitLegacyZExt(PrevConvertOp->getArg(0));
// PrevConvertOp = None;
// } else {
// PrevConvertOp = Op;
// }
// }
// break;
// }
// case dwarf::DW_OP_stack_value:
// LocationKind = Implicit;
// break;
case dwarf::DW_OP_swap:
// assert(!isRegisterLocation());
emitOp(dwarf::DW_OP_swap);
break;
case dwarf::DW_OP_xderef:
// assert(!isRegisterLocation());
emitOp(dwarf::DW_OP_xderef);
break;
case dwarf::DW_OP_deref_size:
emitOp(dwarf::DW_OP_deref_size);
emitData1(static_cast<uint8_t>(Op->getArg(0)));
break;
// case dwarf::DW_OP_LLVM_tag_offset:
// TagOffset = Op->getArg(0);
// break;
case dwarf::DW_OP_regx:
emitOp(dwarf::DW_OP_regx);
emitUnsigned(Op->getArg(0));
break;
case dwarf::DW_OP_bregx:
emitOp(dwarf::DW_OP_bregx);
emitUnsigned(Op->getArg(0));
emitSigned(Op->getArg(1));
break;
default:
llvm_unreachable("unhandled opcode found in expression");
}
}
// if (isImplicitLocation() && !isParameterValue())
// // Turn this into an implicit location description.
// addStackValue();
return true;
}
void DwarfExpression::finalize() {
// assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
//// Emit any outstanding DW_OP_piece operations to mask out subregisters.
// if (SubRegisterSizeInBits == 0)
// return;
//// Don't emit a DW_OP_piece for a subregister at offset 0.
// if (SubRegisterOffsetInBits == 0)
// return;
// addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits);
}
|