aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/NaCl/Reader
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode/NaCl/Reader')
-rw-r--r--lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp49
-rw-r--r--lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h19
2 files changed, 65 insertions, 3 deletions
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
index f9d479767b..1bbbf4516a 100644
--- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
+++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
@@ -1314,6 +1314,15 @@ bool NaClBitcodeReader::InstallInstruction(
return false;
}
+Value *NaClBitcodeReader::ConvertOpToScalar(Value *Op, BasicBlock *BB) {
+ if (Op->getType()->isPointerTy()) {
+ Instruction *Conversion = new PtrToIntInst(Op, IntPtrType);
+ InstallInstruction(BB, Conversion);
+ return Conversion;
+ }
+ return Op;
+}
+
Value *NaClBitcodeReader::ConvertOpToType(Value *Op, Type *T, BasicBlock *BB) {
// Note: Currently only knows how to add inttoptr and bitcast type
// conversions for non-phi nodes, since these are the only elided
@@ -1326,7 +1335,7 @@ Value *NaClBitcodeReader::ConvertOpToType(Value *Op, Type *T, BasicBlock *BB) {
if (OpTy->isPointerTy()) {
Conversion = new BitCastInst(Op, T);
- } else if (OpTy->isIntegerTy()) {
+ } else if (OpTy == IntPtrType) {
Conversion = new IntToPtrInst(Op, T);
}
@@ -1341,6 +1350,10 @@ Value *NaClBitcodeReader::ConvertOpToType(Value *Op, Type *T, BasicBlock *BB) {
return Conversion;
}
+Type *NaClBitcodeReader::ConvertTypeToScalarType(Type *T) {
+ return T->isPointerTy() ? IntPtrType : T;
+}
+
/// ParseFunctionBody - Lazily parse the specified function body block.
bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
DEBUG(dbgs() << "-> ParseFunctionBody\n");
@@ -1427,6 +1440,9 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
OpNum+1 > Record.size())
return Error("Invalid BINOP record");
+ LHS = ConvertOpToScalar(LHS, CurBB);
+ RHS = ConvertOpToScalar(RHS, CurBB);
+
int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
if (Opc == -1) return Error("Invalid BINOP record");
I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
@@ -1475,6 +1491,24 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
int Opc = GetDecodedCastOpcode(Record[OpNum+1]);
if (Opc == -1 || ResTy == 0)
return Error("Invalid CAST record");
+
+ if (GetPNaClVersion() == 2) {
+ // If a ptrtoint cast was elided on the argument of the cast,
+ // add it back. Note: The casts allowed here should match the
+ // casts in NaClValueEnumerator::ExpectsScalarValue.
+ switch (Opc) {
+ case Instruction::Trunc:
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ Op = ConvertOpToScalar(Op, CurBB);
+ break;
+ default:
+ break;
+ }
+ }
+
I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
break;
}
@@ -1489,6 +1523,9 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
popValue(Record, &OpNum, NextValueNo, &Cond))
return Error("Invalid SELECT record");
+ TrueVal = ConvertOpToScalar(TrueVal, CurBB);
+ FalseVal = ConvertOpToScalar(FalseVal, CurBB);
+
// expect i1
if (Cond->getType() != Type::getInt1Ty(Context))
return Error("Invalid SELECT condition type");
@@ -1507,6 +1544,9 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
OpNum+1 != Record.size())
return Error("Invalid CMP record");
+ LHS = ConvertOpToScalar(LHS, CurBB);
+ RHS = ConvertOpToScalar(RHS, CurBB);
+
if (LHS->getType()->isFPOrFPVectorTy())
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
else
@@ -1612,6 +1652,9 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
Type *Ty = getTypeByID(Record[0]);
if (!Ty) return Error("Invalid PHI record");
+ // TODO(kschimpf): Fix handling of converting types for values,
+ // to handle elided casts, once the bitcode writer knows how.
+
PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2);
for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
@@ -1684,6 +1727,7 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
case 2:
if (OpNum+1 != Record.size())
return Error("Invalid STORE record");
+ Val = ConvertOpToScalar(Val, CurBB);
Ptr = ConvertOpToType(Ptr, Val->getType()->getPointerTo(), CurBB);
I = new StoreInst(Val, Ptr, false, (1 << Record[OpNum]) >> 1);
break;
@@ -1695,6 +1739,9 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) {
if (Record.size() < 2)
return Error("Invalid CALL record");
+ // TODO(kschimpf): Fix handling of type conversion to arguments for PNaCl,
+ // to handle elided casts, once the bitcode writer knows how.
+
unsigned CCInfo = Record[0];
unsigned OpNum = 1;
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
index 805bddf0b2..814ef44efb 100644
--- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
+++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
@@ -20,6 +20,7 @@
#include "llvm/Bitcode/NaCl/NaClBitstreamReader.h"
#include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h"
#include "llvm/GVMaterializer.h"
+#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/ValueHandle.h"
@@ -167,6 +168,9 @@ class NaClBitcodeReader : public GVMaterializer {
/// \brief True if we should only accept supported bitcode format.
bool AcceptSupportedBitcodeOnly;
+ /// \brief Integer type use for PNaCl conversion of pointers.
+ Type *IntPtrType;
+
public:
explicit NaClBitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
bool AcceptSupportedOnly = true)
@@ -174,7 +178,8 @@ public:
LazyStreamer(0), NextUnreadBit(0), SeenValueSymbolTable(false),
ValueList(C),
SeenFirstFunctionBody(false), UseRelativeIDs(false),
- AcceptSupportedBitcodeOnly(AcceptSupportedOnly) {
+ AcceptSupportedBitcodeOnly(AcceptSupportedOnly),
+ IntPtrType(IntegerType::get(C, PNaClIntPtrTypeBitSize)) {
}
explicit NaClBitcodeReader(DataStreamer *streamer, LLVMContext &C,
bool AcceptSupportedOnly = true)
@@ -182,7 +187,8 @@ public:
LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false),
ValueList(C),
SeenFirstFunctionBody(false), UseRelativeIDs(false),
- AcceptSupportedBitcodeOnly(AcceptSupportedOnly) {
+ AcceptSupportedBitcodeOnly(AcceptSupportedOnly),
+ IntPtrType(IntegerType::get(C, PNaClIntPtrTypeBitSize)) {
}
~NaClBitcodeReader() {
FreeState();
@@ -275,6 +281,15 @@ private:
/// an appropriate error message and calls Error).
Value *ConvertOpToType(Value *Op, Type *T, BasicBlock *BB);
+ /// \brief If Op is a scalar value, this is a nop. If Op is a
+ /// pointer value, a PtrToInt instruction is inserted (in BB) to
+ /// convert Op to an integer.
+ Value *ConvertOpToScalar(Value *Op, BasicBlock *BB);
+
+ /// \brief Returns the corresponding, PNaCl non-pointer equivalent
+ /// for the given type.
+ Type *ConvertTypeToScalarType(Type *T);
+
/// \brief Install instruction I into basic block BB.
bool InstallInstruction(BasicBlock *BB, Instruction *I);