Introduce the "@llvm.dbg.value" debug intrinsic.

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
This commit is contained in:
Victor Hernandez 2009-12-07 19:36:34 +00:00
parent bc39a795f4
commit 2f9dac721d
4 changed files with 60 additions and 0 deletions

View File

@ -492,6 +492,7 @@ namespace llvm {
const Type *EmptyStructPtr; // "{}*". const Type *EmptyStructPtr; // "{}*".
Function *DeclareFn; // llvm.dbg.declare Function *DeclareFn; // llvm.dbg.declare
Function *ValueFn; // llvm.dbg.value
DIFactory(const DIFactory &); // DO NOT IMPLEMENT DIFactory(const DIFactory &); // DO NOT IMPLEMENT
void operator=(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 *InsertDeclare(llvm::Value *Storage, DIVariable D,
Instruction *InsertBefore); 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: private:
Constant *GetTagConstant(unsigned TAG); Constant *GetTagConstant(unsigned TAG);
}; };

View File

@ -70,6 +70,7 @@ namespace llvm {
case Intrinsic::dbg_region_start: case Intrinsic::dbg_region_start:
case Intrinsic::dbg_region_end: case Intrinsic::dbg_region_end:
case Intrinsic::dbg_declare: case Intrinsic::dbg_declare:
case Intrinsic::dbg_value:
return true; return true;
default: return false; 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. /// MemIntrinsic - This is the common base class for memset/memcpy/memmove.
/// ///
struct MemIntrinsic : public IntrinsicInst { struct MemIntrinsic : public IntrinsicInst {

View File

@ -290,6 +290,9 @@ let Properties = [IntrNoMem] in {
def int_dbg_func_start : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>; def int_dbg_func_start : Intrinsic<[llvm_void_ty], [llvm_metadata_ty]>;
def int_dbg_declare : Intrinsic<[llvm_void_ty], def int_dbg_declare : Intrinsic<[llvm_void_ty],
[llvm_descriptor_ty, llvm_metadata_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----------------------===// //===------------------ Exception Handling Intrinsics----------------------===//

View File

@ -1050,6 +1050,35 @@ Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd); 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. // DebugInfoFinder implementations.