aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp')
-rw-r--r--lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp63
1 files changed, 63 insertions, 0 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