Index: include/llvm/IR/DIBuilder.h =================================================================== --- include/llvm/IR/DIBuilder.h +++ include/llvm/IR/DIBuilder.h @@ -766,6 +766,28 @@ DIScope *Scope = nullptr, VarDecl VD = nullptr); + /// When we loose order of some function's parameter we create new + /// simple call site in order to be able to keep tracing it after + /// ISel phase trough its location. To secure that every parameter + /// has its own call site param metadata, even the simplest, we + /// call this function. + /// \param DCS Old call site that contains number of required + /// new empty call site parameter metadata + /// \param Scope Scope of caller function used to determeine + /// from which DISubprogram given DICallSite should + /// be deleted. + /// \param Context New Context for metadata. + DICallSite *createSimpleCallSite(DICallSite *DCS, DILocalScope *Scope, + LLVMContext &Context); + + /// Erase call site from subprogram that is contains given scope. + /// \param CallSite CallSite pointer that should be droped from + // following function scope. + // \param Scope Scope that should be used to determine from + // which DISubprogram given CallSite should be + // deleted. + void eraseCallSite(DICallSite *CallSite, DIScope *Scope); + /// This creates new descriptor for a namespace with the specified /// parent scope. /// \param Scope Namespace scope Index: include/llvm/IR/DebugInfoMetadata.h =================================================================== --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -1958,6 +1958,12 @@ return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram(); } + // Create DICallSite that has same number of simple call site parameters as + // CS. + static DICallSite *getTrivialCallSite(const DICallSite *CS, + DILocalScope *NewScope, + LLVMContext &Context); + static bool classof(const Metadata *MD) { return MD->getMetadataID() == DICallSiteKind; } Index: lib/IR/DIBuilder.cpp =================================================================== --- lib/IR/DIBuilder.cpp +++ lib/IR/DIBuilder.cpp @@ -832,6 +832,43 @@ return DICallSiteParam::get(VMContext, ArgNo, Expr); } +void DIBuilder::eraseCallSite(DICallSite *CallSite, DIScope *Scope) { + DISubprogram *Fn = getDISubprogram(Scope); + assert(Fn && "Missing subprogram for callsite"); + DINodeArray OldElements = Fn->getRetainedNodes(); + SmallVector Elements; + + for (unsigned i = 0; i < OldElements.size(); ++i) { + if (DICallSite *CS = dyn_cast_or_null(OldElements[i])) { + if (CS != CallSite) + Elements.push_back(CS); + } else + Elements.push_back(OldElements[i]); + } + + DINodeArray AV = getOrCreateArray(Elements); + Fn->replaceElements(AV); +} + +DICallSite *DIBuilder::createSimpleCallSite(DICallSite *DCS, + DILocalScope *Scope, + LLVMContext &Context) { + auto *Node = DICallSite::getTrivialCallSite(DCS, Scope, Context); + + DISubprogram *Fn = getDISubprogram(Scope); + assert(Fn && "Missing subprogram for callsite"); + DINodeArray Elements = Fn->getRetainedNodes(); + SmallVector NewElements; + for (unsigned i = 0; i < Elements.size(); ++i) + NewElements.push_back(Elements[i]); + NewElements.push_back(DCS); + + DINodeArray AV = getOrCreateArray(NewElements); + Fn->replaceElements(AV); + + return Node; +} + DISubprogram *DIBuilder::createTempFunctionFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, Index: lib/IR/DebugInfoMetadata.cpp =================================================================== --- lib/IR/DebugInfoMetadata.cpp +++ lib/IR/DebugInfoMetadata.cpp @@ -673,6 +673,20 @@ DEFINE_GETIMPL_STORE(DICallSite, (Line), Ops); } +DICallSite *DICallSite::getTrivialCallSite(const DICallSite *CS, + DILocalScope *NewScope, + LLVMContext &Context) { + DIExpression *Expr = DIExpression::get(CS->getContext(), {}); + SmallVector CallSiteParams; + for (unsigned ArgNo = 1; ArgNo <= CS->getParameters().size(); ArgNo++) + CallSiteParams.push_back( + DICallSiteParam::get(CS->getContext(), ArgNo, Expr)); + llvm::DINodeArray NewParamArray = + MDTuple::get(CS->getContext(), CallSiteParams); + return DICallSite::get(Context, NewScope, CS->getFile(), NewParamArray, 1, + CS->getCalledSubprogram()); +} + DICallSiteParam *DICallSiteParam::getImpl(LLVMContext &Context, unsigned ArgNo, Metadata *Var, Metadata *Expr, StorageType Storage, Index: lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp =================================================================== --- lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp +++ lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp @@ -63,6 +63,9 @@ CurrBB.getParent(), JoinBB); Builder.SetInsertPoint(LibCallBB); Instruction *LibCall = Call->clone(); + // Do not track call site info from partially inlined lib calls. + if (LibCall->getMetadata(LLVMContext::MD_call_site)) + LibCall->setMetadata(LLVMContext::MD_call_site, nullptr); Builder.Insert(LibCall); Builder.CreateBr(JoinBB); Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -2299,6 +2299,18 @@ break; case LLVMContext::MD_dbg: llvm_unreachable("getAllMetadataOtherThanDebugLoc returned a MD_dbg"); + case LLVMContext::MD_call_site: { + DILocalScope *Scope = K->getDebugLoc()->getScope(); + auto &M = *(K->getModule()); + DIBuilder DIB(M, false); + + K->setMetadata(LLVMContext::MD_call_site, + DIB.createSimpleCallSite(cast(JMD), Scope, + K->getContext())); + DIB.eraseCallSite(cast(JMD), Scope); + DIB.eraseCallSite(cast(KMD), Scope); + break; + } case LLVMContext::MD_tbaa: K->setMetadata(Kind, MDNode::getMostGenericTBAA(JMD, KMD)); break; @@ -2368,7 +2380,7 @@ LLVMContext::MD_noalias, LLVMContext::MD_range, LLVMContext::MD_invariant_load, LLVMContext::MD_nonnull, LLVMContext::MD_invariant_group, LLVMContext::MD_align, - LLVMContext::MD_dereferenceable, + LLVMContext::MD_dereferenceable, LLVMContext::MD_call_site, LLVMContext::MD_dereferenceable_or_null, LLVMContext::MD_access_group}; combineMetadata(K, J, KnownIDs, KDominatesJ);