18c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar/* 28c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * Copyright 2015, The Android Open Source Project 38c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * 48c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * Licensed under the Apache License, Version 2.0 (the "License"); 58c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * you may not use this file except in compliance with the License. 68c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * You may obtain a copy of the License at 78c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * 88c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * http://www.apache.org/licenses/LICENSE-2.0 98c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * 108c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * Unless required by applicable law or agreed to in writing, software 118c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * distributed under the License is distributed on an "AS IS" BASIS, 128c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * See the License for the specific language governing permissions and 148c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * limitations under the License. 158c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar */ 168c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 17a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "Assert.h" 18a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "Log.h" 19a2dd52f0710c214e00c1a13e25116e1af5eec77aJean-Luc Brouillet#include "RSUtils.h" 208c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 218c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar#include <algorithm> 228c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar#include <vector> 238c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 248c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar#include <llvm/IR/CallSite.h> 258c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar#include <llvm/IR/Type.h> 268c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar#include <llvm/IR/Instructions.h> 278c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar#include <llvm/IR/Module.h> 288c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar#include <llvm/IR/Function.h> 298c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar#include <llvm/Pass.h> 308c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 318c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainarnamespace { // anonymous namespace 328c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 338c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainarstatic const bool kDebug = false; 348c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 358c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar/* RSX86_64CallConvPass: This pass scans for calls to Renderscript functions in 368c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * the CPU reference driver. For such calls, it identifies the 378c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * pass-by-reference large-object pointer arguments introduced by the frontend 388c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * to conform to the AArch64 calling convention (AAPCS). These pointer 398c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * arguments are converted to pass-by-value to match the calling convention of 408c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar * the CPU reference driver. 418c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar */ 428c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainarclass RSX86_64CallConvPass: public llvm::ModulePass { 438c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainarprivate: 448c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar bool IsRSFunctionOfInterest(llvm::Function &F) { 458c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Only Renderscript functions that are not defined locally be considered 468c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (!F.empty()) // defined locally 478c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return false; 488c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 498c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // llvm intrinsic or internal function 508c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::StringRef FName = F.getName(); 518c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (FName.startswith("llvm.")) 528c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return false; 538c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 548c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // All other functions need to be checked for large-object parameters. 558c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Disallowed (non-Renderscript) functions are detected by a different pass. 568c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return true; 578c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 588c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 598c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Test if this argument needs to be converted to pass-by-value. 608c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar bool IsDerefNeeded(llvm::Function *F, llvm::Argument &Arg) { 618c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar unsigned ArgNo = Arg.getArgNo(); 628c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::Type *ArgTy = Arg.getType(); 638c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 648c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Do not consider arguments with 'sret' attribute. Parameters with this 658c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // attribute are actually pointers to structure return values. 668c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (Arg.hasStructRetAttr()) 678c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return false; 688c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 698c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Dereference needed only if type is a pointer to a struct 708c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (!ArgTy->isPointerTy() || !ArgTy->getPointerElementType()->isStructTy()) 718c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return false; 728c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 738c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Dereference needed only for certain RS struct objects. 748c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::Type *StructTy = ArgTy->getPointerElementType(); 75abfa7852d33391671d972614bb21990c5f32ee2bStephen Hines if (!isRsObjectType(StructTy)) 768c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return false; 778c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 788c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // TODO Find a better way to encode exceptions 798c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::StringRef FName = F->getName(); 808c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // rsSetObject's first parameter is a pointer 818c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (FName.find("rsSetObject") != std::string::npos && ArgNo == 0) 828c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return false; 838c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // rsClearObject's first parameter is a pointer 848c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (FName.find("rsClearObject") != std::string::npos && ArgNo == 0) 858c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return false; 8602c61f6dbe389424a97b2ffd333bcfc6e1e952c1Yang Ni // rsForEachInternal's fifth parameter is a pointer 8702c61f6dbe389424a97b2ffd333bcfc6e1e952c1Yang Ni if (FName.find("rsForEachInternal") != std::string::npos && ArgNo == 4) 8802c61f6dbe389424a97b2ffd333bcfc6e1e952c1Yang Ni return false; 898c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 908c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return true; 918c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 928c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 938c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Compute which arguments to this function need be converted to pass-by-value 948c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar bool FillArgsToDeref(llvm::Function *F, std::vector<unsigned> &ArgNums) { 958c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar bccAssert(ArgNums.size() == 0); 968c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 978c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar for (auto &Arg: F->getArgumentList()) { 988c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (IsDerefNeeded(F, Arg)) { 998c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar ArgNums.push_back(Arg.getArgNo()); 1008c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1018c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (kDebug) { 1028c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar ALOGV("Lowering argument %u for function %s\n", Arg.getArgNo(), 1038c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar F->getName().str().c_str()); 1048c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1058c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1068c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1078c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return ArgNums.size() > 0; 1088c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1098c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1108c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::Function *RedefineFn(llvm::Function *OrigFn, 1118c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar std::vector<unsigned> &ArgsToDeref) { 1128c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1138c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::FunctionType *FTy = OrigFn->getFunctionType(); 1148c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar std::vector<llvm::Type *> Params(FTy->param_begin(), FTy->param_end()); 1158c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1168c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::FunctionType *NewTy = llvm::FunctionType::get(FTy->getReturnType(), 1178c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar Params, 1188c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar FTy->isVarArg()); 1198c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::Function *NewFn = llvm::Function::Create(NewTy, 1208c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar OrigFn->getLinkage(), 1218c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar OrigFn->getName(), 1228c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar OrigFn->getParent()); 1238c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1248c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Add the ByVal attribute to the attribute list corresponding to this 1258c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // argument. The list at index (i+1) corresponds to the i-th argument. The 1268c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // list at index 0 corresponds to the return value's attribute. 1278c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar for (auto i: ArgsToDeref) { 1288c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar NewFn->addAttribute(i+1, llvm::Attribute::ByVal); 1298c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1308c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1318c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar NewFn->copyAttributesFrom(OrigFn); 1328c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar NewFn->takeName(OrigFn); 1338c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1348c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar for (auto AI=OrigFn->arg_begin(), AE=OrigFn->arg_end(), 1358c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar NAI=NewFn->arg_begin(); 1368c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar AI != AE; ++ AI, ++NAI) { 137f229c40f0d2da19985e68955aef1a06ce4121e63Pirama Arumuga Nainar NAI->takeName(&*AI); 1388c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1398c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1408c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return NewFn; 1418c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1428c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1438c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar void ReplaceCallInsn(llvm::CallSite &CS, 1448c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::Function *NewFn, 1458c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar std::vector<unsigned> &ArgsToDeref) { 1468c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1478c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::CallInst *CI = llvm::cast<llvm::CallInst>(CS.getInstruction()); 1488c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar std::vector<llvm::Value *> Args(CS.arg_begin(), CS.arg_end()); 1498c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar auto NewCI = llvm::CallInst::Create(NewFn, Args, "", CI); 1508c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1518c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Add the ByVal attribute to the attribute list corresponding to this 1528c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // argument. The list at index (i+1) corresponds to the i-th argument. The 1538c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // list at index 0 corresponds to the return value's attribute. 1548c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar for (auto i: ArgsToDeref) { 1558c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar NewCI->addAttribute(i+1, llvm::Attribute::ByVal); 1568c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1578c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (CI->isTailCall()) 1588c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar NewCI->setTailCall(); 1598c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1608c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (!CI->getType()->isVoidTy()) 1618c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar CI->replaceAllUsesWith(NewCI); 1628c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1638c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar CI->eraseFromParent(); 1648c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1658c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1668c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainarpublic: 1678c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar static char ID; 1688c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1698c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar RSX86_64CallConvPass() 1708c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar : ModulePass (ID) { 1718c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1728c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1738c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override { 1748c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // This pass does not use any other analysis passes, but it does 1758c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // modify the existing functions in the module (thus altering the CFG). 1768c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1778c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1788c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar bool runOnModule(llvm::Module &M) override { 1798c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Avoid adding Functions and altering FunctionList while iterating over it 1808c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // by collecting functions and processing them later. 1818c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar std::vector<llvm::Function *> FunctionsToHandle; 1828c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1838c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar auto &FunctionList = M.getFunctionList(); 1848c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar for (auto &OrigFn: FunctionList) { 1858c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (!IsRSFunctionOfInterest(OrigFn)) 1868c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar continue; 1878c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar FunctionsToHandle.push_back(&OrigFn); 1888c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 1898c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1908c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar for (auto OrigFn: FunctionsToHandle) { 1918c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar std::vector<unsigned> ArgsToDeref; 1928c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar if (!FillArgsToDeref(OrigFn, ArgsToDeref)) 1938c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar continue; 1948c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 1958c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar // Replace all calls to OrigFn and erase it from parent. 1968c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::Function *NewFn = RedefineFn(OrigFn, ArgsToDeref); 1978c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar while (!OrigFn->use_empty()) { 1988c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar llvm::CallSite CS(OrigFn->user_back()); 1998c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar ReplaceCallInsn(CS, NewFn, ArgsToDeref); 2008c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 2018c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar OrigFn->eraseFromParent(); 2028c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 2038c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 2048c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return FunctionsToHandle.size() > 0; 2058c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar } 2068c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 2078c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar}; 2088c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 2098c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar} 2108c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 2118c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainarchar RSX86_64CallConvPass::ID = 0; 2128c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 2138c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainarstatic llvm::RegisterPass<RSX86_64CallConvPass> X("X86-64-calling-conv", 2148c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar "remove AArch64 assumptions from calls in X86-64"); 2158c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 2168c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainarnamespace bcc { 2178c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 2188c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainarllvm::ModulePass * 2198c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga NainarcreateRSX86_64CallConvPass() { 2208c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar return new RSX86_64CallConvPass(); 2218c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar} 2228c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar 2238c24f8d1d75b619130e8bfce204ed9695362d4a1Pirama Arumuga Nainar} 224