@@ -1180,6 +1180,184 @@ bool FastISel::selectCall(const User *I) {
1180
1180
return lowerCall (Call);
1181
1181
}
1182
1182
1183
+ void FastISel::handleDbgInfo (const Instruction *II) {
1184
+ if (!II->hasDbgValues ())
1185
+ return ;
1186
+
1187
+ // Clear any metadata.
1188
+ MIMD = MIMetadata ();
1189
+
1190
+ // Reverse order of debug records, because fast-isel walks through backwards.
1191
+ for (DPValue &DPV : llvm::reverse (II->getDbgValueRange ())) {
1192
+ flushLocalValueMap ();
1193
+ recomputeInsertPt ();
1194
+
1195
+ Value *V = nullptr ;
1196
+ if (!DPV.hasArgList ())
1197
+ V = DPV.getVariableLocationOp (0 );
1198
+
1199
+ bool Res = false ;
1200
+ if (DPV.getType () == DPValue::LocationType::Value) {
1201
+ Res = lowerDbgValue (V, DPV.getExpression (), DPV.getVariable (),
1202
+ DPV.getDebugLoc ());
1203
+ } else {
1204
+ assert (DPV.getType () == DPValue::LocationType::Declare);
1205
+ if (FuncInfo.PreprocessedDPVDeclares .contains (&DPV))
1206
+ continue ;
1207
+ Res = lowerDbgDeclare (V, DPV.getExpression (), DPV.getVariable (),
1208
+ DPV.getDebugLoc ());
1209
+ }
1210
+
1211
+ if (!Res)
1212
+ LLVM_DEBUG (dbgs () << " Dropping debug-info for " << DPV << " \n " ;);
1213
+ }
1214
+ }
1215
+
1216
+ bool FastISel::lowerDbgValue (const Value *V, DIExpression *Expr,
1217
+ DILocalVariable *Var, const DebugLoc &DL) {
1218
+ // This form of DBG_VALUE is target-independent.
1219
+ const MCInstrDesc &II = TII.get (TargetOpcode::DBG_VALUE);
1220
+ if (!V || isa<UndefValue>(V)) {
1221
+ // DI is either undef or cannot produce a valid DBG_VALUE, so produce an
1222
+ // undef DBG_VALUE to terminate any prior location.
1223
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL, II, false , 0U , Var, Expr);
1224
+ return true ;
1225
+ }
1226
+ if (const auto *CI = dyn_cast<ConstantInt>(V)) {
1227
+ // See if there's an expression to constant-fold.
1228
+ if (Expr)
1229
+ std::tie (Expr, CI) = Expr->constantFold (CI);
1230
+ if (CI->getBitWidth () > 64 )
1231
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL, II)
1232
+ .addCImm (CI)
1233
+ .addImm (0U )
1234
+ .addMetadata (Var)
1235
+ .addMetadata (Expr);
1236
+ else
1237
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL, II)
1238
+ .addImm (CI->getZExtValue ())
1239
+ .addImm (0U )
1240
+ .addMetadata (Var)
1241
+ .addMetadata (Expr);
1242
+ return true ;
1243
+ }
1244
+ if (const auto *CF = dyn_cast<ConstantFP>(V)) {
1245
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL, II)
1246
+ .addFPImm (CF)
1247
+ .addImm (0U )
1248
+ .addMetadata (Var)
1249
+ .addMetadata (Expr);
1250
+ return true ;
1251
+ }
1252
+ if (const auto *Arg = dyn_cast<Argument>(V);
1253
+ Arg && Expr && Expr->isEntryValue ()) {
1254
+ // As per the Verifier, this case is only valid for swift async Args.
1255
+ assert (Arg->hasAttribute (Attribute::AttrKind::SwiftAsync));
1256
+
1257
+ Register Reg = getRegForValue (Arg);
1258
+ for (auto [PhysReg, VirtReg] : FuncInfo.RegInfo ->liveins ())
1259
+ if (Reg == VirtReg || Reg == PhysReg) {
1260
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL, II, false /* IsIndirect*/ ,
1261
+ PhysReg, Var, Expr);
1262
+ return true ;
1263
+ }
1264
+
1265
+ LLVM_DEBUG (dbgs () << " Dropping dbg.value: expression is entry_value but "
1266
+ " couldn't find a physical register\n " );
1267
+ return false ;
1268
+ }
1269
+ if (auto SI = FuncInfo.StaticAllocaMap .find (dyn_cast<AllocaInst>(V));
1270
+ SI != FuncInfo.StaticAllocaMap .end ()) {
1271
+ MachineOperand FrameIndexOp = MachineOperand::CreateFI (SI->second );
1272
+ bool IsIndirect = false ;
1273
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL, II, IsIndirect, FrameIndexOp,
1274
+ Var, Expr);
1275
+ return true ;
1276
+ }
1277
+ if (Register Reg = lookUpRegForValue (V)) {
1278
+ // FIXME: This does not handle register-indirect values at offset 0.
1279
+ if (!FuncInfo.MF ->useDebugInstrRef ()) {
1280
+ bool IsIndirect = false ;
1281
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL, II, IsIndirect, Reg, Var,
1282
+ Expr);
1283
+ return true ;
1284
+ }
1285
+ // If using instruction referencing, produce this as a DBG_INSTR_REF,
1286
+ // to be later patched up by finalizeDebugInstrRefs.
1287
+ SmallVector<MachineOperand, 1 > MOs ({MachineOperand::CreateReg (
1288
+ /* Reg */ Reg, /* isDef */ false , /* isImp */ false ,
1289
+ /* isKill */ false , /* isDead */ false ,
1290
+ /* isUndef */ false , /* isEarlyClobber */ false ,
1291
+ /* SubReg */ 0 , /* isDebug */ true )});
1292
+ SmallVector<uint64_t , 2 > Ops ({dwarf::DW_OP_LLVM_arg, 0 });
1293
+ auto *NewExpr = DIExpression::prependOpcodes (Expr, Ops);
1294
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL,
1295
+ TII.get (TargetOpcode::DBG_INSTR_REF), /* IsIndirect*/ false , MOs,
1296
+ Var, NewExpr);
1297
+ return true ;
1298
+ }
1299
+ return false ;
1300
+ }
1301
+
1302
+ bool FastISel::lowerDbgDeclare (const Value *Address, DIExpression *Expr,
1303
+ DILocalVariable *Var, const DebugLoc &DL) {
1304
+ if (!Address || isa<UndefValue>(Address)) {
1305
+ LLVM_DEBUG (dbgs () << " Dropping debug info (bad/undef address)\n " );
1306
+ return false ;
1307
+ }
1308
+
1309
+ std::optional<MachineOperand> Op;
1310
+ if (Register Reg = lookUpRegForValue (Address))
1311
+ Op = MachineOperand::CreateReg (Reg, false );
1312
+
1313
+ // If we have a VLA that has a "use" in a metadata node that's then used
1314
+ // here but it has no other uses, then we have a problem. E.g.,
1315
+ //
1316
+ // int foo (const int *x) {
1317
+ // char a[*x];
1318
+ // return 0;
1319
+ // }
1320
+ //
1321
+ // If we assign 'a' a vreg and fast isel later on has to use the selection
1322
+ // DAG isel, it will want to copy the value to the vreg. However, there are
1323
+ // no uses, which goes counter to what selection DAG isel expects.
1324
+ if (!Op && !Address->use_empty () && isa<Instruction>(Address) &&
1325
+ (!isa<AllocaInst>(Address) ||
1326
+ !FuncInfo.StaticAllocaMap .count (cast<AllocaInst>(Address))))
1327
+ Op = MachineOperand::CreateReg (FuncInfo.InitializeRegForValue (Address),
1328
+ false );
1329
+
1330
+ if (Op) {
1331
+ assert (Var->isValidLocationForIntrinsic (DL) &&
1332
+ " Expected inlined-at fields to agree" );
1333
+ if (FuncInfo.MF ->useDebugInstrRef () && Op->isReg ()) {
1334
+ // If using instruction referencing, produce this as a DBG_INSTR_REF,
1335
+ // to be later patched up by finalizeDebugInstrRefs. Tack a deref onto
1336
+ // the expression, we don't have an "indirect" flag in DBG_INSTR_REF.
1337
+ SmallVector<uint64_t , 3 > Ops (
1338
+ {dwarf::DW_OP_LLVM_arg, 0 , dwarf::DW_OP_deref});
1339
+ auto *NewExpr = DIExpression::prependOpcodes (Expr, Ops);
1340
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL,
1341
+ TII.get (TargetOpcode::DBG_INSTR_REF), /* IsIndirect*/ false , *Op,
1342
+ Var, NewExpr);
1343
+ return true ;
1344
+ }
1345
+
1346
+ // A dbg.declare describes the address of a source variable, so lower it
1347
+ // into an indirect DBG_VALUE.
1348
+ BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , DL,
1349
+ TII.get (TargetOpcode::DBG_VALUE), /* IsIndirect*/ true , *Op, Var,
1350
+ Expr);
1351
+ return true ;
1352
+ }
1353
+
1354
+ // We can't yet handle anything else here because it would require
1355
+ // generating code, thus altering codegen because of debug info.
1356
+ LLVM_DEBUG (
1357
+ dbgs () << " Dropping debug info (no materialized reg for address)\n " );
1358
+ return false ;
1359
+ }
1360
+
1183
1361
bool FastISel::selectIntrinsicCall (const IntrinsicInst *II) {
1184
1362
switch (II->getIntrinsicID ()) {
1185
1363
default :
@@ -1209,153 +1387,28 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
1209
1387
return true ;
1210
1388
1211
1389
const Value *Address = DI->getAddress ();
1212
- if (!Address || isa<UndefValue>(Address)) {
1213
- LLVM_DEBUG (dbgs () << " Dropping debug info for " << *DI
1214
- << " (bad/undef address)\n " );
1215
- return true ;
1216
- }
1390
+ if (!lowerDbgDeclare (Address, DI->getExpression (), DI->getVariable (),
1391
+ MIMD.getDL ()))
1392
+ LLVM_DEBUG (dbgs () << " Dropping debug info for " << *DI);
1217
1393
1218
- std::optional<MachineOperand> Op;
1219
- if (Register Reg = lookUpRegForValue (Address))
1220
- Op = MachineOperand::CreateReg (Reg, false );
1221
-
1222
- // If we have a VLA that has a "use" in a metadata node that's then used
1223
- // here but it has no other uses, then we have a problem. E.g.,
1224
- //
1225
- // int foo (const int *x) {
1226
- // char a[*x];
1227
- // return 0;
1228
- // }
1229
- //
1230
- // If we assign 'a' a vreg and fast isel later on has to use the selection
1231
- // DAG isel, it will want to copy the value to the vreg. However, there are
1232
- // no uses, which goes counter to what selection DAG isel expects.
1233
- if (!Op && !Address->use_empty () && isa<Instruction>(Address) &&
1234
- (!isa<AllocaInst>(Address) ||
1235
- !FuncInfo.StaticAllocaMap .count (cast<AllocaInst>(Address))))
1236
- Op = MachineOperand::CreateReg (FuncInfo.InitializeRegForValue (Address),
1237
- false );
1238
-
1239
- if (Op) {
1240
- assert (DI->getVariable ()->isValidLocationForIntrinsic (MIMD.getDL ()) &&
1241
- " Expected inlined-at fields to agree" );
1242
- if (FuncInfo.MF ->useDebugInstrRef () && Op->isReg ()) {
1243
- // If using instruction referencing, produce this as a DBG_INSTR_REF,
1244
- // to be later patched up by finalizeDebugInstrRefs. Tack a deref onto
1245
- // the expression, we don't have an "indirect" flag in DBG_INSTR_REF.
1246
- SmallVector<uint64_t , 3 > Ops (
1247
- {dwarf::DW_OP_LLVM_arg, 0 , dwarf::DW_OP_deref});
1248
- auto *NewExpr = DIExpression::prependOpcodes (DI->getExpression (), Ops);
1249
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD.getDL (),
1250
- TII.get (TargetOpcode::DBG_INSTR_REF), /* IsIndirect*/ false , *Op,
1251
- DI->getVariable (), NewExpr);
1252
- } else {
1253
- // A dbg.declare describes the address of a source variable, so lower it
1254
- // into an indirect DBG_VALUE.
1255
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD.getDL (),
1256
- TII.get (TargetOpcode::DBG_VALUE), /* IsIndirect*/ true , *Op,
1257
- DI->getVariable (), DI->getExpression ());
1258
- }
1259
- } else {
1260
- // We can't yet handle anything else here because it would require
1261
- // generating code, thus altering codegen because of debug info.
1262
- LLVM_DEBUG (dbgs () << " Dropping debug info for " << *DI
1263
- << " (no materialized reg for address)\n " );
1264
- }
1265
1394
return true ;
1266
1395
}
1267
1396
case Intrinsic::dbg_value: {
1268
1397
// This form of DBG_VALUE is target-independent.
1269
1398
const DbgValueInst *DI = cast<DbgValueInst>(II);
1270
- const MCInstrDesc &II = TII.get (TargetOpcode::DBG_VALUE);
1271
1399
const Value *V = DI->getValue ();
1272
1400
DIExpression *Expr = DI->getExpression ();
1273
1401
DILocalVariable *Var = DI->getVariable ();
1402
+ if (DI->hasArgList ())
1403
+ // Signal that we don't have a location for this.
1404
+ V = nullptr ;
1405
+
1274
1406
assert (Var->isValidLocationForIntrinsic (MIMD.getDL ()) &&
1275
1407
" Expected inlined-at fields to agree" );
1276
- if (!V || isa<UndefValue>(V) || DI->hasArgList ()) {
1277
- // DI is either undef or cannot produce a valid DBG_VALUE, so produce an
1278
- // undef DBG_VALUE to terminate any prior location.
1279
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD.getDL (), II, false , 0U ,
1280
- Var, Expr);
1281
- return true ;
1282
- }
1283
- if (const auto *CI = dyn_cast<ConstantInt>(V)) {
1284
- // See if there's an expression to constant-fold.
1285
- if (Expr)
1286
- std::tie (Expr, CI) = Expr->constantFold (CI);
1287
- if (CI->getBitWidth () > 64 )
1288
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD, II)
1289
- .addCImm (CI)
1290
- .addImm (0U )
1291
- .addMetadata (Var)
1292
- .addMetadata (Expr);
1293
- else
1294
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD, II)
1295
- .addImm (CI->getZExtValue ())
1296
- .addImm (0U )
1297
- .addMetadata (Var)
1298
- .addMetadata (Expr);
1299
- return true ;
1300
- }
1301
- if (const auto *CF = dyn_cast<ConstantFP>(V)) {
1302
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD, II)
1303
- .addFPImm (CF)
1304
- .addImm (0U )
1305
- .addMetadata (Var)
1306
- .addMetadata (Expr);
1307
- return true ;
1308
- }
1309
- if (const auto *Arg = dyn_cast<Argument>(V);
1310
- Arg && Expr && Expr->isEntryValue ()) {
1311
- // As per the Verifier, this case is only valid for swift async Args.
1312
- assert (Arg->hasAttribute (Attribute::AttrKind::SwiftAsync));
1313
-
1314
- Register Reg = getRegForValue (Arg);
1315
- for (auto [PhysReg, VirtReg] : FuncInfo.RegInfo ->liveins ())
1316
- if (Reg == VirtReg || Reg == PhysReg) {
1317
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD.getDL (), II,
1318
- false /* IsIndirect*/ , PhysReg, Var, Expr);
1319
- return true ;
1320
- }
1321
1408
1322
- LLVM_DEBUG (dbgs () << " Dropping dbg.value: expression is entry_value but "
1323
- " couldn't find a physical register\n "
1324
- << *DI << " \n " );
1325
- return true ;
1326
- }
1327
- if (auto SI = FuncInfo.StaticAllocaMap .find (dyn_cast<AllocaInst>(V));
1328
- SI != FuncInfo.StaticAllocaMap .end ()) {
1329
- MachineOperand FrameIndexOp = MachineOperand::CreateFI (SI->second );
1330
- bool IsIndirect = false ;
1331
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD.getDL (), II, IsIndirect,
1332
- FrameIndexOp, Var, Expr);
1333
- return true ;
1334
- }
1335
- if (Register Reg = lookUpRegForValue (V)) {
1336
- // FIXME: This does not handle register-indirect values at offset 0.
1337
- if (!FuncInfo.MF ->useDebugInstrRef ()) {
1338
- bool IsIndirect = false ;
1339
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD.getDL (), II, IsIndirect,
1340
- Reg, Var, Expr);
1341
- return true ;
1342
- }
1343
- // If using instruction referencing, produce this as a DBG_INSTR_REF,
1344
- // to be later patched up by finalizeDebugInstrRefs.
1345
- SmallVector<MachineOperand, 1 > MOs ({MachineOperand::CreateReg (
1346
- /* Reg */ Reg, /* isDef */ false , /* isImp */ false ,
1347
- /* isKill */ false , /* isDead */ false ,
1348
- /* isUndef */ false , /* isEarlyClobber */ false ,
1349
- /* SubReg */ 0 , /* isDebug */ true )});
1350
- SmallVector<uint64_t , 2 > Ops ({dwarf::DW_OP_LLVM_arg, 0 });
1351
- auto *NewExpr = DIExpression::prependOpcodes (Expr, Ops);
1352
- BuildMI (*FuncInfo.MBB , FuncInfo.InsertPt , MIMD.getDL (),
1353
- TII.get (TargetOpcode::DBG_INSTR_REF), /* IsIndirect*/ false , MOs,
1354
- Var, NewExpr);
1355
- return true ;
1356
- }
1357
- // We don't know how to handle other cases, so we drop.
1358
- LLVM_DEBUG (dbgs () << " Dropping debug info for " << *DI << " \n " );
1409
+ if (!lowerDbgValue (V, Expr, Var, MIMD.getDL ()))
1410
+ LLVM_DEBUG (dbgs () << " Dropping debug info for " << *DI << " \n " );
1411
+
1359
1412
return true ;
1360
1413
}
1361
1414
case Intrinsic::dbg_label: {
0 commit comments