aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h')
-rw-r--r--lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h96
1 files changed, 80 insertions, 16 deletions
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
index 814ef44efb..762088887f 100644
--- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
+++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
@@ -21,6 +21,7 @@
#include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h"
#include "llvm/GVMaterializer.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/ValueHandle.h"
@@ -29,6 +30,46 @@
namespace llvm {
class MemoryBuffer;
class LLVMContext;
+ class CastInst;
+
+// Models a Cast. Used to cache casts created in a basic block by the
+// PNaCl bitcode reader.
+struct NaClBitcodeReaderCast {
+ // Fields of the conversion.
+ Instruction::CastOps Op;
+ Type *Ty;
+ Value *Val;
+
+ NaClBitcodeReaderCast(Instruction::CastOps Op, Type *Ty, Value *Val)
+ : Op(Op), Ty(Ty), Val(Val) {}
+};
+
+// Models the data structure used to hash/compare Casts in a DenseMap.
+template<>
+struct DenseMapInfo<NaClBitcodeReaderCast> {
+public:
+ static NaClBitcodeReaderCast getEmptyKey() {
+ return NaClBitcodeReaderCast(Instruction::CastOpsEnd,
+ DenseMapInfo<Type*>::getEmptyKey(),
+ DenseMapInfo<Value*>::getEmptyKey());
+ }
+ static NaClBitcodeReaderCast getTombstoneKey() {
+ return NaClBitcodeReaderCast(Instruction::CastOpsEnd,
+ DenseMapInfo<Type*>::getTombstoneKey(),
+ DenseMapInfo<Value*>::getTombstoneKey());
+ }
+ static unsigned getHashValue(const NaClBitcodeReaderCast &C) {
+ std::pair<int, std::pair<Type*, Value*> > Tuple;
+ Tuple.first = C.Op;
+ Tuple.second.first = C.Ty;
+ Tuple.second.second = C.Val;
+ return DenseMapInfo<std::pair<int, std::pair<Type*, Value*> > >::getHashValue(Tuple);
+ }
+ static bool isEqual(const NaClBitcodeReaderCast &LHS,
+ const NaClBitcodeReaderCast &RHS) {
+ return LHS.Op == RHS.Op && LHS.Ty == RHS.Ty && LHS.Val == RHS.Val;
+ }
+};
//===----------------------------------------------------------------------===//
// NaClBitcodeReaderValueList Class
@@ -83,8 +124,8 @@ public:
// already been declared.
bool createValueFwdRef(unsigned Idx, Type *Ty);
- // Declares the type of the forward-referenced constant Idx. Returns
- // 0 if an error occurred.
+ // Declares the type of the forward-referenced constant Idx.
+ // Returns 0 if an error occurred.
// TODO(kschimpf) Convert these to be like createValueFwdRef and
// getValueFwdRef.
Constant *getConstantFwdRef(unsigned Idx, Type *Ty);
@@ -103,7 +144,7 @@ public:
// was forward referenced).
void AssignValue(Value *V, unsigned Idx);
- // Assigns Idx to the given global variable. If the Idx currently has
+ // Assigns Idx to the given global variable. If the Idx currently has
// a forward reference (built by createGlobalVarFwdRef(unsigned Idx)),
// replaces uses of the global variable forward reference with the
// value GV.
@@ -133,9 +174,20 @@ class NaClBitcodeReader : public GVMaterializer {
NaClBitcodeReaderValueList ValueList;
SmallVector<SmallVector<uint64_t, 64>, 64> UseListRecords;
+ // Holds information about each BasicBlock in the function being read.
+ struct BasicBlockInfo {
+ // A basic block within the function being modeled.
+ BasicBlock *BB;
+ // The set of generated conversions.
+ DenseMap<NaClBitcodeReaderCast, CastInst*> CastMap;
+ // The set of generated conversions that were added for phi nodes,
+ // and may need thier parent basic block defined.
+ std::vector<CastInst*> PhiCasts;
+ };
+
/// FunctionBBs - While parsing a function body, this is a list of the basic
/// blocks for the function.
- std::vector<BasicBlock*> FunctionBBs;
+ std::vector<BasicBlockInfo> FunctionBBs;
// When reading the module header, this list is populated with functions that
// have bodies later in the file.
@@ -147,7 +199,7 @@ class NaClBitcodeReader : public GVMaterializer {
UpgradedIntrinsicMap UpgradedIntrinsics;
// Several operations happen after the module header has been read, but
- // before function bodies are processed. This keeps track of whether
+ // before function bodies are processed. This keeps track of whether
// we've done this yet.
bool SeenFirstFunctionBody;
@@ -226,14 +278,14 @@ private:
return Header.GetPNaClVersion();
}
Type *getTypeByID(unsigned ID);
- // Returns the value associated with ID. The value must already exist,
+ // Returns the value associated with ID. The value must already exist,
// or a forward referenced value created by getOrCreateFnVaueByID.
Value *getFnValueByID(unsigned ID) {
return ValueList.getValueFwdRef(ID);
}
BasicBlock *getBasicBlock(unsigned ID) const {
if (ID >= FunctionBBs.size()) return 0; // Invalid ID
- return FunctionBBs[ID];
+ return FunctionBBs[ID].BB;
}
/// \brief Read a value out of the specified record from slot '*Slot'.
@@ -273,18 +325,30 @@ private:
return getFnValueByID(ValNo);
}
- /// \brief Add instructions to cast Op to the given type T into block BB.
- /// Follows rules for pointer conversion as defined in
- /// llvm/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp.
+ /// \brief Create an (elided) cast instruction for basic block
+ /// BBIndex. Op is the type of cast. V is the value to cast. CT
+ /// is the type to convert V to. DeferInsertion defines whether the
+ /// generated conversion should also be installed into basic block
+ /// BBIndex. Note: For PHI nodes, we don't insert when created
+ /// (i.e. DeferInsertion=true), since they must be inserted at the end
+ /// of the corresponding incoming basic block.
+ CastInst *CreateCast(unsigned BBIndex, Instruction::CastOps Op,
+ Type *CT, Value *V, bool DeferInsertion = false);
+
+ /// \brief Add instructions to cast Op to the given type T into
+ /// block BBIndex. Follows rules for pointer conversion as defined
+ /// in llvm/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp.
///
/// Returns 0 if unable to generate conversion value (also generates
/// 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);
+ Value *ConvertOpToType(Value *Op, Type *T, unsigned BBIndex);
+
+ /// \brief If Op is a scalar value, this is a nop. If Op is a
+ /// pointer value, a PtrToInt instruction is inserted (in BBIndex)
+ /// to convert Op to an integer. For defaults on DeferInsertion,
+ /// see comments for method CreateCast.
+ Value *ConvertOpToScalar(Value *Op, unsigned BBIndex,
+ bool DeferInsertion = false);
/// \brief Returns the corresponding, PNaCl non-pointer equivalent
/// for the given type.