1*b5893f02SDimitry Andric //===-- AMDGPUFixFunctionBitcasts.cpp - Fix function bitcasts -------------===//
2*b5893f02SDimitry Andric //
3*b5893f02SDimitry Andric //                     The LLVM Compiler Infrastructure
4*b5893f02SDimitry Andric //
5*b5893f02SDimitry Andric // This file is distributed under the University of Illinois Open Source
6*b5893f02SDimitry Andric // License. See LICENSE.TXT for details.
7*b5893f02SDimitry Andric //
8*b5893f02SDimitry Andric //===----------------------------------------------------------------------===//
9*b5893f02SDimitry Andric ///
10*b5893f02SDimitry Andric /// \file
11*b5893f02SDimitry Andric /// Promote indirect (bitcast) calls to direct calls when they are statically
12*b5893f02SDimitry Andric /// known to be direct. Required when InstCombine is not run (e.g. at OptNone)
13*b5893f02SDimitry Andric /// because AMDGPU does not support indirect calls.
14*b5893f02SDimitry Andric ///
15*b5893f02SDimitry Andric //===----------------------------------------------------------------------===//
16*b5893f02SDimitry Andric 
17*b5893f02SDimitry Andric #include "AMDGPU.h"
18*b5893f02SDimitry Andric #include "llvm/IR/InstVisitor.h"
19*b5893f02SDimitry Andric #include "llvm/Transforms/Utils/CallPromotionUtils.h"
20*b5893f02SDimitry Andric 
21*b5893f02SDimitry Andric using namespace llvm;
22*b5893f02SDimitry Andric 
23*b5893f02SDimitry Andric #define DEBUG_TYPE "amdgpu-fix-function-bitcasts"
24*b5893f02SDimitry Andric 
25*b5893f02SDimitry Andric namespace {
26*b5893f02SDimitry Andric class AMDGPUFixFunctionBitcasts final
27*b5893f02SDimitry Andric     : public ModulePass,
28*b5893f02SDimitry Andric       public InstVisitor<AMDGPUFixFunctionBitcasts> {
29*b5893f02SDimitry Andric 
30*b5893f02SDimitry Andric   bool runOnModule(Module &M) override;
31*b5893f02SDimitry Andric 
32*b5893f02SDimitry Andric   bool Modified;
33*b5893f02SDimitry Andric 
34*b5893f02SDimitry Andric public:
visitCallSite(CallSite CS)35*b5893f02SDimitry Andric   void visitCallSite(CallSite CS) {
36*b5893f02SDimitry Andric     if (CS.getCalledFunction())
37*b5893f02SDimitry Andric       return;
38*b5893f02SDimitry Andric     auto Callee = dyn_cast<Function>(CS.getCalledValue()->stripPointerCasts());
39*b5893f02SDimitry Andric     if (Callee && isLegalToPromote(CS, Callee)) {
40*b5893f02SDimitry Andric       promoteCall(CS, Callee);
41*b5893f02SDimitry Andric       Modified = true;
42*b5893f02SDimitry Andric     }
43*b5893f02SDimitry Andric   }
44*b5893f02SDimitry Andric 
45*b5893f02SDimitry Andric   static char ID;
AMDGPUFixFunctionBitcasts()46*b5893f02SDimitry Andric   AMDGPUFixFunctionBitcasts() : ModulePass(ID) {}
47*b5893f02SDimitry Andric };
48*b5893f02SDimitry Andric } // End anonymous namespace
49*b5893f02SDimitry Andric 
50*b5893f02SDimitry Andric char AMDGPUFixFunctionBitcasts::ID = 0;
51*b5893f02SDimitry Andric char &llvm::AMDGPUFixFunctionBitcastsID = AMDGPUFixFunctionBitcasts::ID;
52*b5893f02SDimitry Andric INITIALIZE_PASS(AMDGPUFixFunctionBitcasts, DEBUG_TYPE,
53*b5893f02SDimitry Andric                 "Fix function bitcasts for AMDGPU", false, false)
54*b5893f02SDimitry Andric 
createAMDGPUFixFunctionBitcastsPass()55*b5893f02SDimitry Andric ModulePass *llvm::createAMDGPUFixFunctionBitcastsPass() {
56*b5893f02SDimitry Andric   return new AMDGPUFixFunctionBitcasts();
57*b5893f02SDimitry Andric }
58*b5893f02SDimitry Andric 
runOnModule(Module & M)59*b5893f02SDimitry Andric bool AMDGPUFixFunctionBitcasts::runOnModule(Module &M) {
60*b5893f02SDimitry Andric   Modified = false;
61*b5893f02SDimitry Andric   visit(M);
62*b5893f02SDimitry Andric   return Modified;
63*b5893f02SDimitry Andric }
64