Introduce the "@llvm.dbg.value" debug intrinsic.
authorVictor Hernandez <vhernandez@apple.com>
Mon, 7 Dec 2009 19:36:34 +0000 (19:36 +0000)
committerVictor Hernandez <vhernandez@apple.com>
Mon, 7 Dec 2009 19:36:34 +0000 (19:36 +0000)
The semantics of llvm.dbg.value are that starting from where it is executed, an offset into the specified user source variable is specified to get a new value.

An example:
  call void @llvm.dbg.value(metadata !{ i32 7 }, i64 0, metadata !2)
Here the user source variable associated with metadata #2 gets the value "i32 7" at offset 0.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90788 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/DebugInfo.h
include/llvm/IntrinsicInst.h
include/llvm/Intrinsics.td
lib/Analysis/DebugInfo.cpp

index c560ec2e3594ec3bab4e2de4671a5c3b299e58f6..4ddde0158af1f7d2012e5ec7c22ef89e608b9811 100644 (file)
@@ -492,6 +492,7 @@ namespace llvm {
 
     const Type *EmptyStructPtr; // "{}*".
     Function *DeclareFn;     // llvm.dbg.declare
+    Function *ValueFn;       // llvm.dbg.value
 
     DIFactory(const DIFactory &);     // DO NOT IMPLEMENT
     void operator=(const DIFactory&); // DO NOT IMPLEMENT
@@ -639,6 +640,13 @@ namespace llvm {
     Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D,
                                Instruction *InsertBefore);
 
+    /// InsertValue - Insert a new llvm.dbg.value intrinsic call.
+    Instruction *InsertValue(llvm::Value *V, llvm::Value *Offset,
+                             DIVariable D, BasicBlock *InsertAtEnd);
+
+    /// InsertValue - Insert a new llvm.dbg.value intrinsic call.
+    Instruction *InsertValue(llvm::Value *V, llvm::Value *Offset,
+                             DIVariable D, Instruction *InsertBefore);
   private:
     Constant *GetTagConstant(unsigned TAG);
   };
index 1e1dca2ebab7c997fd0a02c93c07bf4b560ef1ae..a5164092962b7c940e8b7c271208509c7fb4d49f 100644 (file)
@@ -70,6 +70,7 @@ namespace llvm {
       case Intrinsic::dbg_region_start:
       case Intrinsic::dbg_region_end:
       case Intrinsic::dbg_declare:
+      case Intrinsic::dbg_value:
         return true;
       default: return false;
       }
@@ -171,6 +172,25 @@ namespace llvm {
     }
   };
 
+  /// DbgValueInst - This represents the llvm.dbg.value instruction.
+  ///
+  struct DbgValueInst : public DbgInfoIntrinsic {
+    Value *getValue()  const {
+      return cast<MDNode>(getOperand(1))->getElement(0);
+    }
+    Value *getOffset() const { return getOperand(2); }
+    MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); }
+
+    // Methods for support type inquiry through isa, cast, and dyn_cast:
+    static inline bool classof(const DbgValueInst *) { return true; }
+    static inline bool classof(const IntrinsicInst *I) {
+      return I->getIntrinsicID() == Intrinsic::dbg_value;
+    }
+    static inline bool classof(const Value *V) {
+      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+    }
+  };
+
   /// MemIntrinsic - This is the common base class for memset/memcpy/memmove.
   ///
   struct MemIntrinsic : public IntrinsicInst {
index b3b0678a24ecdb14edc5fe93f141899db7eafd1f..6ff87ba150667ded55da085900be5580100f1d85 100644 (file)
@@ -290,6 +290,9 @@ let Properties = [IntrNoMem] in {
   def int_dbg_func_start   : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>;
   def int_dbg_declare      : Intrinsic<[llvm_void_ty],
                                        [llvm_descriptor_ty, llvm_metadata_ty]>;
+  def int_dbg_value       : Intrinsic<[llvm_void_ty],
+                                       [llvm_metadata_ty, llvm_i64_ty,
+                                        llvm_metadata_ty]>;
 }
 
 //===------------------ Exception Handling Intrinsics----------------------===//
index 4a012ce484f01e9fced800fc73b2ffb7af686177..74d9e1e179448702605629d006fe3cf7a3744b1b 100644 (file)
@@ -1050,6 +1050,35 @@ Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
   return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd);
 }
 
+/// InsertValue - Insert a new llvm.dbg.value intrinsic call.
+Instruction *DIFactory::InsertValue(Value *V, Value *Offset, DIVariable D,
+                                    Instruction *InsertBefore) {
+  assert(V && "no value passed to dbg.value");
+  assert(Offset->getType() == Type::getInt64Ty(V->getContext()) &&
+         "offset must be i64");
+  if (!ValueFn)
+    ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
+
+  Value *Elts[] = { V };
+  Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset,
+                    D.getNode() };
+  return CallInst::Create(ValueFn, Args, Args+3, "", InsertBefore);
+}
+
+/// InsertValue - Insert a new llvm.dbg.value intrinsic call.
+Instruction *DIFactory::InsertValue(Value *V, Value *Offset, DIVariable D,
+                                    BasicBlock *InsertAtEnd) {
+  assert(V && "no value passed to dbg.value");
+  assert(Offset->getType() == Type::getInt64Ty(V->getContext()) &&
+         "offset must be i64");
+  if (!ValueFn)
+    ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
+
+  Value *Elts[] = { V };
+  Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset,
+                    D.getNode() };
+  return CallInst::Create(ValueFn, Args, Args+3, "", InsertAtEnd);
+}
 
 //===----------------------------------------------------------------------===//
 // DebugInfoFinder implementations.