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