diff options
author | Eric Christopher <echristo@apple.com> | 2009-10-27 00:52:25 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2009-10-27 00:52:25 +0000 |
commit | 7b5e61707a128a222e5e7ab20eb8154ca81001cb (patch) | |
tree | 97b92c485a5974efe8f986bc8d97daae634ff793 | |
parent | dd22a45acc24ff1e4954fda753c555a6365d1dec (diff) |
Add objectsize intrinsic and hook it up through codegen. Doesn't
do anything than return "I don't know" at the moment.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85189 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Intrinsics.td | 5 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 12 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SimplifyLibCalls.cpp | 25 |
3 files changed, 42 insertions, 0 deletions
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index e6d8007523..c0cf00e8ee 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -259,6 +259,11 @@ def int_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>; def int_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>; def int_siglongjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>; +// Internal interface for object size checking +def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i32_ty], + [IntrReadArgMem]>, + GCCBuiltin<"__builtin_object_size">; + //===-------------------- Bit Manipulation Intrinsics ---------------------===// // diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index f3a0622157..b220d55f54 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -4204,6 +4204,18 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { DAG.setRoot(Result); return 0; } + case Intrinsic::objectsize: { + // If we don't know by now, we're never going to know. + ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(2)); + + assert(CI && "Non-constant type in __builtin_object_size?"); + + if (CI->getZExtValue() < 2) + setValue(&I, DAG.getConstant(-1, MVT::i32)); + else + setValue(&I, DAG.getConstant(0, MVT::i32)); + return 0; + } case Intrinsic::var_annotation: // Discard annotate attributes return 0; diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index e186601505..575c93b9dd 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -509,6 +509,27 @@ static bool IsOnlyUsedInZeroEqualityComparison(Value *V) { } //===----------------------------------------------------------------------===// +// Miscellaneous LibCall/Intrinsic Optimizations +//===----------------------------------------------------------------------===// + +namespace { +struct SizeOpt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + // TODO: We can do more with this, but delaying to here should be no change + // in behavior. + ConstantInt *Const = dyn_cast<ConstantInt>(CI->getOperand(2)); + + if (!Const) return 0; + + if (Const->getZExtValue() < 2) + return Constant::getAllOnesValue(Const->getType()); + else + return ConstantInt::get(Const->getType(), 0); + } +}; +} + +//===----------------------------------------------------------------------===// // String and Memory LibCall Optimizations //===----------------------------------------------------------------------===// @@ -1548,6 +1569,7 @@ namespace { // Formatting and IO Optimizations SPrintFOpt SPrintF; PrintFOpt PrintF; FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF; + SizeOpt ObjectSize; bool Modified; // This is only used by doInitialization. public: @@ -1653,6 +1675,9 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["fwrite"] = &FWrite; Optimizations["fputs"] = &FPuts; Optimizations["fprintf"] = &FPrintF; + + // Miscellaneous + Optimizations["llvm.objectsize"] = &ObjectSize; } |