aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp')
-rw-r--r--lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp45
1 files changed, 31 insertions, 14 deletions
diff --git a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
index 8cfdf13240..5dbc525eec 100644
--- a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
+++ b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
@@ -18,6 +18,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/Debug.h"
@@ -466,11 +467,13 @@ static bool AllUsesExpectsNormalizedPtr(const Instruction *I2P) {
return true;
}
-// Given Value that uses scalar value Arg, returns true if the bitcode
-// writer can assume that Value always expects Arg to be scalar. This
-// function is used to infer cases where PtrToInt casts can be
-// removed.
-static bool ExpectsScalarValue(const Value *V, const Instruction *Arg) {
+// Given Value V that uses argument Arg, returns true if the bitcode
+// writer can assume that V always expects Arg to be scalar.
+// Assumes that the type of Arg is the integer type used to model
+// pointers. Hence, this function determines if the reader would
+// have to convert pointers to integer. This function
+// is used to infer cases where PtrToInt casts can be removed.
+static bool ExpectsIntPtrType(const Value *V, const Instruction *Arg) {
const Instruction *I = dyn_cast<Instruction>(V);
if (I == 0) return false;
@@ -487,6 +490,7 @@ static bool ExpectsScalarValue(const Value *V, const Instruction *Arg) {
case Instruction::UIToFP:
case Instruction::SIToFP:
case Instruction::ICmp:
+ case Instruction::Ret:
return true;
case Instruction::Store:
return Arg == I->getOperand(0);
@@ -495,8 +499,12 @@ static bool ExpectsScalarValue(const Value *V, const Instruction *Arg) {
return Arg == Op->getTrueValue() || Arg == Op->getFalseValue();
}
case Instruction::Call: {
- // All operands (except the first, which must be a function pointer),
- // can be scalar values.
+ // All operands (except the first, which must be a function
+ // pointer), must be scalar values. Note: For non-intrinsic
+ // calls, this is a requirement of the PNaCl ABI. For intrinsic
+ // calls, the condition that Arg's type is an integer type,
+ // implies that the intrinsic (for that argument) requires a
+ // scalar value at that position.
const CallInst *Call = cast<CallInst>(I);
return Call->getCalledValue() != Arg;
}
@@ -504,13 +512,12 @@ static bool ExpectsScalarValue(const Value *V, const Instruction *Arg) {
}
}
-// Returns true if the bitcode reader and writer can assume that the
-// uses of the given PtrToInt expect scalar values (i.e. non-pointer),
-// and hence, we can elide the PtrToInt cast.
-static bool AllUsesExpectsScalarValue(const Instruction *I) {
+// Returns true if all uses of I expect I to be scalar, given that
+// the type of I is the integer type used to represent pointers.
+static bool AllUsesExpectsIntPtrType(const Instruction *I) {
for (Value::const_use_iterator Use = I->use_begin(), UseEnd = I->use_end();
Use != UseEnd; ++Use) {
- if (!ExpectsScalarValue(*Use, I)) return false;
+ if (!ExpectsIntPtrType(*Use, I)) return false;
}
// If reached, all uses expect a scalar value (and hence we know how
// to automatically add it back), or there were no uses (and hence
@@ -518,10 +525,20 @@ static bool AllUsesExpectsScalarValue(const Instruction *I) {
return true;
}
+// Returns true if the value is an intrinsic instruction returns
+// a pointer value.
+static inline bool IsIntrinsicReturningPtr(const Value *V) {
+ if (const IntrinsicInst *ICall = dyn_cast<IntrinsicInst>(V)) {
+ return V->getType()->isPointerTy();
+ }
+ return false;
+}
+
// Returns true if the value is an InherentPtr (as defined in
// llvm/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp).
static inline bool IsInherentPtr(const Value *V) {
- return isa<AllocaInst>(V) || isa<GlobalValue>(V);
+ return isa<AllocaInst>(V) || isa<GlobalValue>(V) ||
+ IsIntrinsicReturningPtr(V);
}
// Note: This function is based on the comments in
@@ -547,7 +564,7 @@ const Value *NaClValueEnumerator::ElideCasts(const Value *V) {
case Instruction::PtrToInt:
if (IsIntPtrType(I->getType()) &&
IsInherentPtr(I->getOperand(0)) &&
- AllUsesExpectsScalarValue(I)) {
+ AllUsesExpectsIntPtrType(I)) {
V = I->getOperand(0);
}
break;