diff options
Diffstat (limited to 'lib/Bitcode')
-rw-r--r-- | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp | 24 | ||||
-rw-r--r-- | lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp | 18 |
2 files changed, 28 insertions, 14 deletions
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp index 40f8842b3b..ede06b2457 100644 --- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp +++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp @@ -1315,28 +1315,28 @@ bool NaClBitcodeReader::InstallInstruction( } Value *NaClBitcodeReader::ConvertOpToType(Value *Op, Type *T, BasicBlock *BB) { - // Note: Currently only knows how to add inttoptr type conversion, since - // this is the only elided instruction in the bitcode writer. + // Note: Currently only knows how to add inttoptr and bitcast type + // conversions for non-phi nodes, since these are the only elided + // instructions in the bitcode writer. + // // TODO(kschimpf): Generalize this as we expand elided conversions. - Value *Conversion = 0; + Instruction *Conversion = 0; Type *OpTy = Op->getType(); if (OpTy == T) return Op; - // Following while loop is only run once. It is used to break on - // erroneous conditions. - while (true) { - if (!OpTy->isIntegerTy()) break; - if (!T->isPointerTy()) break; - Instruction *I = CastInst::Create(Instruction::IntToPtr, Op, T); - if (InstallInstruction(BB, I)) break; - Conversion = I; - break; + if (OpTy->isPointerTy()) { + Conversion = new BitCastInst(Op, T); + } else if (OpTy->isIntegerTy()) { + Conversion = new IntToPtrInst(Op, T); } + if (Conversion == 0) { std::string Message; raw_string_ostream StrM(Message); StrM << "Can't convert " << *Op << " to type " << *T << "\n"; Error(StrM.str()); + } else { + InstallInstruction(BB, Conversion); } return Conversion; } diff --git a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp index 7da01f005e..11e1161bf8 100644 --- a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp +++ b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp @@ -450,7 +450,7 @@ static bool AllowsNormalizedPtr(const Value *V, const Instruction *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) { +static bool AllUsesAllowNormalizedPtr(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; @@ -461,6 +461,12 @@ static bool IntToPtrUsesAllowEliding(const Instruction *I2P) { return true; } +// 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); +} + // Note: This function is based on the comments in // llvm/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp. const Value *NaClValueEnumerator::ElideCasts(const Value *V) { @@ -470,10 +476,18 @@ const Value *NaClValueEnumerator::ElideCasts(const Value *V) { switch (I->getOpcode()) { default: break; + case Instruction::BitCast: + if (I->getType()->isPointerTy() && + AllUsesAllowNormalizedPtr(I) && + IsInherentPtr(I->getOperand(0))) { + return ElideCasts(I->getOperand(0)); + } + break; case Instruction::IntToPtr: - if (IntToPtrUsesAllowEliding(I)) { + if (AllUsesAllowNormalizedPtr(I)) { return ElideCasts(I->getOperand(0)); } + break; } } return V; |