31
31
#include " llvm/Frontend/OpenMP/OMPDeviceConstants.h"
32
32
#include " llvm/Frontend/OpenMP/OMPIRBuilder.h"
33
33
#include " llvm/IR/Constants.h"
34
+ #include " llvm/IR/DebugInfo.h"
34
35
#include " llvm/IR/DebugInfoMetadata.h"
35
36
#include " llvm/IR/DerivedTypes.h"
36
37
#include " llvm/IR/IRBuilder.h"
38
+ #include " llvm/IR/InstIterator.h"
39
+ #include " llvm/IR/IntrinsicInst.h"
37
40
#include " llvm/IR/ReplaceConstant.h"
38
41
#include " llvm/Support/FileSystem.h"
39
42
#include " llvm/TargetParser/Triple.h"
40
43
#include " llvm/Transforms/Utils/BasicBlockUtils.h"
41
44
#include " llvm/Transforms/Utils/ModuleUtils.h"
42
- #include " llvm/IR/InstIterator.h"
43
- #include " llvm/IR/IntrinsicInst.h"
44
45
45
46
#include < any>
46
47
#include < cstdint>
@@ -5464,8 +5465,10 @@ static void updateDebugInfoForDeclareTargetVariables(
5464
5465
}
5465
5466
}
5466
5467
5467
- // This function adds DIOp based expressions in declare target function to
5468
- // generate valid debug info for AMDGPU.
5468
+ // This function handle any adjustments needed in declare target function to
5469
+ // generate valid debug info for AMDGPU. It does 2 main things:
5470
+ // 1. Add alloca for arguments passed by reference.
5471
+ // 2. Add DIOp based expressions
5469
5472
5470
5473
static void updateDebugInfoForDeclareTargetFunctions (
5471
5474
llvm::Function *Fn, LLVM::ModuleTranslation &moduleTranslation) {
@@ -5475,23 +5478,80 @@ static void updateDebugInfoForDeclareTargetFunctions(
5475
5478
if (!llvm::Triple (M.getTargetTriple ()).isAMDGPU ())
5476
5479
return ;
5477
5480
5478
- auto UpdateDebugRecord = [&](auto *DR) {
5481
+ llvm::IRBuilderBase &builder = ompBuilder->Builder ;
5482
+ llvm::OpenMPIRBuilder::InsertPointTy curInsert = builder.saveIP ();
5483
+ unsigned int allocaAS = M.getDataLayout ().getAllocaAddrSpace ();
5484
+ unsigned int defaultAS = M.getDataLayout ().getProgramAddressSpace ();
5485
+
5486
+ builder.SetInsertPoint (Fn->getEntryBlock ().getFirstInsertionPt ());
5487
+
5488
+ llvm::Type *PtrTy = builder.getPtrTy (defaultAS);
5489
+ llvm::Type *AllocaPtrTy = builder.getPtrTy (allocaAS);
5490
+ llvm::DIExprBuilder EB (Fn->getContext ());
5491
+ EB.append <llvm::DIOp::Arg>(0u , AllocaPtrTy);
5492
+ EB.append <llvm::DIOp::Deref>(PtrTy);
5493
+ EB.append <llvm::DIOp::Deref>(PtrTy);
5494
+ llvm::DIExpression *Expr = EB.intoExpression ();
5495
+
5496
+ // flang does not generate allocas for the arguments that are passed by ref.
5497
+ // When the Argument is the location, the quality of the debug information is
5498
+ // poor. The variables are defines on very few addresses and show up as
5499
+ // optimized in most places. One of the reason is the interaction of DI-Op
5500
+ // based ops and regular ones.
5501
+ // Generating alloca seems like the best thing which is done in the loop
5502
+ // below. The users are updated accordingly.
5503
+ for (auto &Arg : Fn->args ()) {
5504
+ if (Arg.getType ()->isPointerTy ()) {
5505
+ llvm::Value *V = builder.CreateAlloca (Arg.getType (), allocaAS, nullptr );
5506
+ if (allocaAS != defaultAS)
5507
+ V = ompBuilder->Builder .CreateAddrSpaceCast (
5508
+ V, builder.getPtrTy (defaultAS));
5509
+ llvm::StoreInst *Store = builder.CreateStore (&Arg, V);
5510
+ llvm::Value *Load = builder.CreateLoad (Arg.getType (), V);
5511
+ llvm::SmallVector<llvm::DbgVariableIntrinsic *> DbgUsers;
5512
+ llvm::SmallVector<llvm::DbgVariableRecord *> DPUsers;
5513
+ llvm::findDbgUsers (DbgUsers, &Arg, &DPUsers);
5514
+ for (auto *DVI : DbgUsers) {
5515
+ DVI->replaceVariableLocationOp (&Arg, V);
5516
+ DVI->setExpression (Expr);
5517
+ }
5518
+ for (auto *DVR : DPUsers) {
5519
+ DVR->replaceVariableLocationOp (&Arg, V);
5520
+ DVR->setExpression (Expr);
5521
+ }
5522
+ Arg.replaceUsesWithIf (Load, [&](const llvm::Use &U) -> bool {
5523
+ // We dont want to replace Arg from the store we created above.
5524
+ if (const auto *SI = dyn_cast<llvm::StoreInst>(U.getUser ()))
5525
+ return SI != Store;
5526
+ return true ;
5527
+ });
5528
+ }
5529
+ }
5530
+ builder.restoreIP (curInsert);
5531
+
5532
+ auto AddExpression = [&](auto *DR) {
5533
+ llvm::DIExpression *Old = DR->getExpression ();
5534
+ // Skip if an expression is already present.
5535
+ if ((Old != nullptr ) && (Old->getNumElements () != 0 ))
5536
+ return ;
5479
5537
for (auto Loc : DR->location_ops ()) {
5480
- llvm::DIExprBuilder ExprBuilder (Fn->getContext ());
5481
5538
llvm::Type *Ty = Loc->getType ();
5482
5539
if (auto *Ref = dyn_cast<llvm::AddrSpaceCastInst>(Loc))
5483
5540
Ty = Ref->getPointerOperand ()->getType ();
5484
- ExprBuilder.append <llvm::DIOp::Arg>(0u , Ty);
5485
- ExprBuilder.append <llvm::DIOp::Deref>(Loc->getType ());
5486
- DR->setExpression (ExprBuilder.intoExpression ());
5541
+ llvm::DIExprBuilder EB (Fn->getContext ());
5542
+ EB.append <llvm::DIOp::Arg>(0u , Ty);
5543
+ EB.append <llvm::DIOp::Deref>(Loc->getType ());
5544
+ DR->setExpression (EB.intoExpression ());
5545
+ break ;
5487
5546
}
5488
5547
};
5548
+
5489
5549
for (llvm::Instruction &I : instructions (Fn)) {
5490
5550
if (auto *DDI = dyn_cast<llvm::DbgVariableIntrinsic>(&I))
5491
- UpdateDebugRecord (DDI);
5551
+ AddExpression (DDI);
5492
5552
5493
5553
for (llvm::DbgVariableRecord &DVR : filterDbgVars (I.getDbgRecordRange ()))
5494
- UpdateDebugRecord (&DVR);
5554
+ AddExpression (&DVR);
5495
5555
}
5496
5556
}
5497
5557
0 commit comments