aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode')
-rw-r--r--lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp63
-rw-r--r--lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h7
-rw-r--r--lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp20
-rw-r--r--lib/Bitcode/NaCl/Writer/NaClValueEnumerator.h5
4 files changed, 94 insertions, 1 deletions
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
index 937012feb8..8b8e9072a8 100644
--- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
+++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
@@ -177,6 +177,10 @@ void NaClBitcodeReaderValueList::AssignGlobalVar(GlobalVariable *GV,
ValuePtrs[Idx] = GV;
}
+void NaClBitcodeReaderValueList::OverwriteValue(Value *V, unsigned Idx) {
+ ValuePtrs[Idx] = V;
+}
+
Value *NaClBitcodeReaderValueList::getValueFwdRef(unsigned Idx) {
if (Idx >= size())
return 0;
@@ -771,6 +775,60 @@ bool NaClBitcodeReader::GlobalCleanup() {
return false;
}
+FunctionType *NaClBitcodeReader::AddPointerTypesToIntrinsicType(
+ StringRef Name, FunctionType *FTy) {
+ Type *ReturnTy = FTy->getReturnType();
+ SmallVector<Type *, 8> ArgTypes(FTy->param_begin(), FTy->param_end());
+
+ // Ideally we wouldn't need a list of supported intrinsics here, but
+ // Intrinsic::* doesn't provide a function for recovering the
+ // expected type of an intrinsic given its full name.
+ // TODO(mseaborn): We could reuse the intrinsic list from
+ // PNaClABIVerifyModule.cpp here.
+ if (Name == "llvm.nacl.read.tp" ||
+ Name == "llvm.stacksave") {
+ ReturnTy = Type::getInt8PtrTy(Context);
+ } else if (Name == "llvm.nacl.setjmp" ||
+ Name == "llvm.nacl.longjmp" ||
+ Name == "llvm.stackrestore" ||
+ Name.startswith("llvm.memset.")) {
+ assert(ArgTypes.size() >= 1);
+ ArgTypes[0] = Type::getInt8PtrTy(Context);
+ } else if (Name.startswith("llvm.memcpy.") ||
+ Name.startswith("llvm.memmove.")) {
+ assert(ArgTypes.size() >= 2);
+ ArgTypes[0] = Type::getInt8PtrTy(Context);
+ ArgTypes[1] = Type::getInt8PtrTy(Context);
+ } else if (Name.startswith("llvm.nacl.atomic.load.") ||
+ Name.startswith("llvm.nacl.atomic.cmpxchg.")) {
+ assert(ArgTypes.size() >= 1);
+ ArgTypes[0] = ReturnTy->getPointerTo();
+ } else if (Name.startswith("llvm.nacl.atomic.store.")) {
+ assert(ArgTypes.size() >= 2);
+ ArgTypes[1] = ArgTypes[0]->getPointerTo();
+ } else if (Name.startswith("llvm.nacl.atomic.rmw.")) {
+ assert(ArgTypes.size() >= 3);
+ ArgTypes[1] = ArgTypes[2]->getPointerTo();
+ }
+ return FunctionType::get(ReturnTy, ArgTypes, false);
+}
+
+void NaClBitcodeReader::AddPointerTypesToIntrinsicParams() {
+ for (unsigned Index = 0, E = ValueList.size(); Index < E; ++Index) {
+ if (Function *Func = dyn_cast<Function>(ValueList[Index])) {
+ if (Func->isIntrinsic()) {
+ FunctionType *FTy = AddPointerTypesToIntrinsicType(
+ Func->getName(), Func->getFunctionType());
+ Function *NewIntrinsic = Function::Create(
+ FTy, GlobalValue::ExternalLinkage, "", TheModule);
+ NewIntrinsic->takeName(Func);
+ ValueList.OverwriteValue(NewIntrinsic, Index);
+ Func->eraseFromParent();
+ }
+ }
+ }
+}
+
bool NaClBitcodeReader::ParseModule(bool Resume) {
DEBUG(dbgs() << "-> ParseModule\n");
if (Resume)
@@ -816,6 +874,11 @@ bool NaClBitcodeReader::ParseModule(bool Resume) {
if (ParseValueSymbolTable())
return true;
SeenValueSymbolTable = true;
+ if (GetPNaClVersion() >= 2) {
+ // Now that we know the names of the intrinsics, we can add
+ // pointer types to the intrinsic declarations' types.
+ AddPointerTypesToIntrinsicParams();
+ }
break;
case naclbitc::FUNCTION_BLOCK_ID:
// If this is the first function body we've seen, reverse the
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
index 318fcb1470..56a894c7d4 100644
--- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
+++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h
@@ -130,6 +130,10 @@ public:
// replaces uses of the global variable forward reference with the
// value GV.
void AssignGlobalVar(GlobalVariable *GV, unsigned Idx);
+
+ // Assigns Idx to the given value, overwriting the existing entry
+ // and possibly modifying the type of the entry.
+ void OverwriteValue(Value *V, unsigned Idx);
};
@@ -333,6 +337,9 @@ private:
/// \brief Install instruction I into basic block BB.
bool InstallInstruction(BasicBlock *BB, Instruction *I);
+ FunctionType *AddPointerTypesToIntrinsicType(StringRef Name,
+ FunctionType *FTy);
+ void AddPointerTypesToIntrinsicParams();
bool ParseModule(bool Resume);
bool ParseTypeTable();
bool ParseTypeTableBody();
diff --git a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
index 64d7661415..42f78baa2a 100644
--- a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
+++ b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp
@@ -298,7 +298,27 @@ void NaClValueEnumerator::EnumerateValue(const Value *VIn) {
}
+Type *NaClValueEnumerator::NormalizeParamType(Type *Ty) const {
+ // Strip pointer types.
+ if (Ty->isPointerTy() && PNaClVersion >= 2)
+ Ty = IntPtrType;
+ return Ty;
+}
+
+Type *NaClValueEnumerator::NormalizeType(Type *Ty) const {
+ if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
+ SmallVector<Type *, 8> ArgTypes;
+ for (unsigned I = 0, E = FTy->getNumParams(); I < E; ++I)
+ ArgTypes.push_back(NormalizeParamType(FTy->getParamType(I)));
+ Ty = FunctionType::get(NormalizeParamType(FTy->getReturnType()),
+ ArgTypes, false);
+ }
+ return Ty;
+}
+
void NaClValueEnumerator::EnumerateType(Type *Ty, bool InsideOptimizeTypes) {
+ Ty = NormalizeType(Ty);
+
// The label type does not need to be given a type ID.
if (Ty->isLabelTy())
return;
diff --git a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.h b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.h
index 71638dd4eb..5f25039e30 100644
--- a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.h
+++ b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.h
@@ -106,7 +106,7 @@ public:
unsigned getValueID(const Value *V) const;
unsigned getTypeID(Type *T) const {
- TypeMapType::const_iterator I = TypeMap.find(T);
+ TypeMapType::const_iterator I = TypeMap.find(NormalizeType(T));
assert(I != TypeMap.end() && "Type not in NaClValueEnumerator!");
return I->second-1;
}
@@ -158,6 +158,9 @@ private:
void OptimizeTypes(const Module *M);
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
+ Type *NormalizeParamType(Type *Ty) const;
+ Type *NormalizeType(Type *Ty) const;
+
void EnumerateValue(const Value *V);
void EnumerateType(Type *T, bool InsideOptimizeTypes=false);
void EnumerateOperandType(const Value *V);