@@ -1180,6 +1180,184 @@ bool FastISel::selectCall(const User *I) {
11801180 return lowerCall (Call);
11811181}
11821182
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+
11831361bool FastISel::selectIntrinsicCall (const IntrinsicInst *II) {
11841362 switch (II->getIntrinsicID ()) {
11851363 default :
@@ -1209,153 +1387,28 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
12091387 return true ;
12101388
12111389 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);
12171393
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- }
12651394 return true ;
12661395 }
12671396 case Intrinsic::dbg_value: {
12681397 // This form of DBG_VALUE is target-independent.
12691398 const DbgValueInst *DI = cast<DbgValueInst>(II);
1270- const MCInstrDesc &II = TII.get (TargetOpcode::DBG_VALUE);
12711399 const Value *V = DI->getValue ();
12721400 DIExpression *Expr = DI->getExpression ();
12731401 DILocalVariable *Var = DI->getVariable ();
1402+ if (DI->hasArgList ())
1403+ // Signal that we don't have a location for this.
1404+ V = nullptr ;
1405+
12741406 assert (Var->isValidLocationForIntrinsic (MIMD.getDL ()) &&
12751407 " 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- }
13211408
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+
13591412 return true ;
13601413 }
13611414 case Intrinsic::dbg_label: {
0 commit comments