aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
diff options
context:
space:
mode:
authorKarl Schimpf <kschimpf@google.com>2013-08-01 07:12:23 -0700
committerKarl Schimpf <kschimpf@google.com>2013-08-01 07:12:23 -0700
commitb9657234ee8b1951db5977a8ffb55a2e5df6d76c (patch)
treeda9f474ea4b35ff767b93715a13a3933f0355f39 /lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
parent365546bcef14965546dc39ebcef35f07a897b9c5 (diff)
Remove the inttoptr dependency from load instructions.
Elides inttoptr casts used (exclusively) in load instructions when PNaClVersion=2. This is an incremental start on removing the inttoptr instruction from the PNaCl wire format (See issue 3544 for more information on the strategy of removing ptrtoint). Also modifies PNaCl bitcode reader/writer to accept PNaClVersion=1 as supported, and PNaClVersion=2 as unsupported but readable (allowing pnacl-freeze and pnacl-thaw to work on such files). Also allows command-line option --pnacl-version for setting PNaClVersion in the PNaCl bitcode writer. Also fixes some problems on PNaCl bitcode headers, using common support to determine when the read/written PNaCl bitcode file is valid. BUG= https://code.google.com/p/nativeclient/issues/detail?id=3544 R=jvoung@chromium.org Review URL: https://codereview.chromium.org/5812155903377408
Diffstat (limited to 'lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp')
-rw-r--r--lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp57
1 files changed, 56 insertions, 1 deletions
diff --git a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
index 3ad224a04f..7da01f005e 100644
--- a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
+++ b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
@@ -231,7 +231,11 @@ void NaClValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST)
EnumerateValue(VI->getValue());
}
-void NaClValueEnumerator::EnumerateValue(const Value *V) {
+void NaClValueEnumerator::EnumerateValue(const Value *VIn) {
+ // Skip over elided values.
+ const Value *V = ElideCasts(VIn);
+ if (V != VIn) return;
+
assert(!V->getType()->isVoidTy() && "Can't insert void values!");
assert(!isa<MDNode>(V) && !isa<MDString>(V) &&
"EnumerateValue doesn't handle Metadata!");
@@ -423,3 +427,54 @@ void NaClValueEnumerator::purgeFunction() {
BasicBlocks.clear();
FnForwardTypeRefs.clear();
}
+
+// Returns true if the bitcode writer can assume that the given
+// argument of the given operation can accept a normalized pointer.
+// Note: This function is based on the concept of NormalizedPtr as
+// defined in llvm/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp.
+static bool AllowsNormalizedPtr(const Value *V, const Instruction *Arg) {
+ const Instruction *I = dyn_cast<Instruction>(V);
+ if (I == 0) return false;
+
+ // TODO(kschimpf) Expand this list to any operation that can handle
+ // normalized pointers. That is loads and stores, function calls, and
+ // instrinsic calls.
+ switch (I->getOpcode()) {
+ default:
+ return false;
+ case Instruction::Load:
+ return I->getOperand(0) == Arg;
+ }
+}
+
+// Returns true if the bitcode reader and writer can assume that the
+// uses of the given inttotpr I2P allow normalized pointers (as
+// defined in llvm/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp).
+static bool IntToPtrUsesAllowEliding(const Instruction *I2P) {
+ for (Value::const_use_iterator u = I2P->use_begin(), e = I2P->use_end();
+ u != e; ++u) {
+ if (!AllowsNormalizedPtr(cast<Value>(*u), I2P)) return false;
+ }
+ // If reached, either all uses have a normalized pointer (and hence
+ // we know how to automatically add it back), or there were no uses (and
+ // hence represents dead code).
+ return true;
+}
+
+// Note: This function is based on the comments in
+// llvm/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp.
+const Value *NaClValueEnumerator::ElideCasts(const Value *V) {
+ if (PNaClVersion == 1) return V;
+ // TODO(kschimpf): Expand this out to cover all cases.
+ if (const Instruction *I = dyn_cast<Instruction>(V)) {
+ switch (I->getOpcode()) {
+ default:
+ break;
+ case Instruction::IntToPtr:
+ if (IntToPtrUsesAllowEliding(I)) {
+ return ElideCasts(I->getOperand(0));
+ }
+ }
+ }
+ return V;
+}