diff options
author | Karl Schimpf <kschimpf@google.com> | 2013-08-01 07:12:23 -0700 |
---|---|---|
committer | Karl Schimpf <kschimpf@google.com> | 2013-08-01 07:12:23 -0700 |
commit | b9657234ee8b1951db5977a8ffb55a2e5df6d76c (patch) | |
tree | da9f474ea4b35ff767b93715a13a3933f0355f39 /lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp | |
parent | 365546bcef14965546dc39ebcef35f07a897b9c5 (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.cpp | 57 |
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; +} |