[clang] (New) Add option to generate additional debug info for expression dereferencing pointer to pointers (PR #95298)

Jeremy Morse via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 13 08:50:12 PDT 2024


================
@@ -5746,6 +5746,57 @@ void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var,
   Var->addDebugInfo(GVE);
 }
 
+void CGDebugInfo::EmitPseudoVariable(CGBuilderTy &Builder,
+                                     llvm::Instruction *Value, QualType Ty) {
+  // Only when -g2 or above is specified, debug info for variables will be
+  // generated.
+  if (CGM.getCodeGenOpts().getDebugInfo() <=
+      llvm::codegenoptions::DebugLineTablesOnly)
+    return;
+
+  llvm::DILocation *DIL = Value->getDebugLoc().get();
+  if (!DIL)
+    return;
+
+  llvm::DIFile *Unit = DIL->getFile();
+  llvm::DIType *Type = getOrCreateType(Ty, Unit);
+
+  // Check if Value is already a declared variable and has debug info, in this
+  // case we have nothing to do. Clang emits declared variable as alloca, and
+  // it is loaded upon use, so we identify such pattern here.
+  if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(Value)) {
+    llvm::Value *Var = Load->getPointerOperand();
+    // There can be implicit type cast applied on a variable if it is an opaque
+    // ptr, in this case its debug info may not match the actual type of object
+    // being used as in the next instruction, so we will need to emit a pseudo
+    // variable for type-casted value.
+    auto DeclareTypeMatches = [&](auto *DbgDeclare) {
+      return DbgDeclare->getVariable()->getType() == Type;
+    };
+    if (any_of(llvm::findDbgDeclares(Var), DeclareTypeMatches) ||
+        any_of(llvm::findDVRDeclares(Var), DeclareTypeMatches))
+      return;
+  }
+
+  // Find the correct location to insert the debug value.
+  llvm::BasicBlock *InsertBB = Value->getParent();
+  llvm::Instruction *InsertBefore = Value->getIterator()->getNextNode();
+  if (llvm::InvokeInst *Invoke = dyn_cast<llvm::InvokeInst>(Value)) {
+    InsertBB = Invoke->getNormalDest();
+    InsertBefore = InsertBB->size() > 0 ? &(InsertBB->front()) : nullptr;
+  }
----------------
jmorse wrote:

Part of the move towards debug-info away from intrinsics involves not inserting with raw instruction pointers, but instead iterators [0]. In practice I believe all that needs to be done is using `InsertBB->begin()` to fetch an iterator, you'll likely need to take `end()` and check it below for the empty-block case.

I understand #94224 provides a more graceful solution by allowing insertion at end(), however that won't land for a short while.

[0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939

https://github.com/llvm/llvm-project/pull/95298


More information about the cfe-commits mailing list