diff options
Diffstat (limited to 'lib/Bitcode')
-rw-r--r-- | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp | 63 | ||||
-rw-r--r-- | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.h | 7 | ||||
-rw-r--r-- | lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp | 20 | ||||
-rw-r--r-- | lib/Bitcode/NaCl/Writer/NaClValueEnumerator.h | 5 |
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); |