16749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni/*
26749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * Copyright 2016, The Android Open Source Project
36749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni *
46749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * Licensed under the Apache License, Version 2.0 (the "License");
56749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * you may not use this file except in compliance with the License.
66749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * You may obtain a copy of the License at
76749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni *
86749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni *     http://www.apache.org/licenses/LICENSE-2.0
96749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni *
106749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * Unless required by applicable law or agreed to in writing, software
116749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * distributed under the License is distributed on an "AS IS" BASIS,
126749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * See the License for the specific language governing permissions and
146749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * limitations under the License.
156749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni */
166749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
176749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include "RSAllocationUtils.h"
186749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
19ae8d5acd42d52078894cdfc1a2d71988387b2e23Yang Ni#include "llvm/ADT/StringRef.h"
209d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung#include "llvm/IR/Constants.h"
216749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include "llvm/IR/GlobalVariable.h"
226749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include "llvm/IR/Instructions.h"
236749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include "llvm/IR/Module.h"
246749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include "llvm/Support/Debug.h"
256749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include "llvm/Support/raw_ostream.h"
266749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
27c7b3a43821ccf0f2b13840246e1895744799cf6bYang Ni#include "cxxabi.h"
28c7b3a43821ccf0f2b13840246e1895744799cf6bYang Ni
296749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include <sstream>
306749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include <unordered_map>
316749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
326749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define DEBUG_TYPE "rs2spirv-rs-allocation-utils"
336749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
346749f541c20e86f5deb6fd421ed5849ef43c275cYang Niusing namespace llvm;
356749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
366749f541c20e86f5deb6fd421ed5849ef43c275cYang Ninamespace rs2spirv {
376749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
386749f541c20e86f5deb6fd421ed5849ef43c275cYang Nibool isRSAllocation(const GlobalVariable &GV) {
396749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  auto *PT = cast<PointerType>(GV.getType());
406749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  DEBUG(PT->dump());
416749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
426749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  auto *VT = PT->getElementType();
436749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  DEBUG(VT->dump());
446749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  std::string TypeName;
456749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  raw_string_ostream RSO(TypeName);
466749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  VT->print(RSO);
476749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  RSO.str(); // Force flush.
486749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  DEBUG(dbgs() << "TypeName: " << TypeName << '\n');
496749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
506749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  return TypeName.find("struct.rs_allocation") != std::string::npos;
516749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni}
526749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
536749f541c20e86f5deb6fd421ed5849ef43c275cYang Nibool getRSAllocationInfo(Module &M, SmallVectorImpl<RSAllocationInfo> &Allocs) {
546749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  DEBUG(dbgs() << "getRSAllocationInfo\n");
556749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  for (auto &GV : M.globals()) {
566749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    if (GV.isDeclaration() || !isRSAllocation(GV))
576749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      continue;
586749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
59c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung    Allocs.push_back({'%' + GV.getName().str(), None, &GV, -1});
606749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  }
616749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
626749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  return true;
636749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni}
646749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
65c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// Collect Allocation access calls into the Calls
66c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// Also update Allocs with assigned ID.
67c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// After calling this function, Allocs would contain the mapping from
68c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung// GV name to the corresponding ID.
696749f541c20e86f5deb6fd421ed5849ef43c275cYang Nibool getRSAllocAccesses(SmallVectorImpl<RSAllocationInfo> &Allocs,
706749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni                        SmallVectorImpl<RSAllocationCallInfo> &Calls) {
716749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  DEBUG(dbgs() << "getRSGEATCalls\n");
726749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  DEBUG(dbgs() << "\n\n~~~~~~~~~~~~~~~~~~~~~\n\n");
736749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
74bf22a8ab4f46a98ee37f95fc0402744132cc3ed2Yang Ni  std::unordered_map<const Value *, const GlobalVariable *> Mapping;
75c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung  int id_assigned = 0;
766749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
776749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  for (auto &A : Allocs) {
786749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    auto *GV = A.GlobalVar;
796749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    std::vector<User *> WorkList(GV->user_begin(), GV->user_end());
806749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    size_t Idx = 0;
816749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
826749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    while (Idx < WorkList.size()) {
836749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      auto *U = WorkList[Idx];
846749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      DEBUG(dbgs() << "Visiting ");
856749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      DEBUG(U->dump());
866749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      ++Idx;
876749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      auto It = Mapping.find(U);
886749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      if (It != Mapping.end()) {
896749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni        if (It->second == GV) {
906749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          continue;
916749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni        } else {
926749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          errs() << "Duplicate global mapping discovered!\n";
936749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          errs() << "\nGlobal: ";
946749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          GV->print(errs());
956749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          errs() << "\nExisting mapping: ";
966749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          It->second->print(errs());
976749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          errs() << "\nUser: ";
986749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          U->print(errs());
996749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          errs() << '\n';
1006749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1016749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          return false;
1026749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni        }
1036749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      }
1046749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1056749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      Mapping[U] = GV;
1066749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      DEBUG(dbgs() << "New mapping: ");
1076749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      DEBUG(U->print(dbgs()));
1086749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      DEBUG(dbgs() << " -> " << GV->getName() << '\n');
1096749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1106749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      if (auto *FCall = dyn_cast<CallInst>(U)) {
1116749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni        if (auto *F = FCall->getCalledFunction()) {
1126749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          const auto FName = F->getName();
1136749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          DEBUG(dbgs() << "Discovered function call to : " << FName << '\n');
1147f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung          // Treat memcpy as moves for the purpose of this analysis
1157f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung          if (FName.startswith("llvm.memcpy")) {
1167f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            assert(FCall->getNumArgOperands() > 0);
1177f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            Value *CopyDest = FCall->getArgOperand(0);
1187f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            // We are interested in the users of the dest operand of
1197f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            // memcpy here
1207f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            Value *LocalCopy = CopyDest->stripPointerCasts();
1217f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            User *NewU = dyn_cast<User>(LocalCopy);
1227f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            assert(NewU);
1237f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            WorkList.push_back(NewU);
1247f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            continue;
1257f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung          }
1266749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1279d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung          char *demangled = __cxxabiv1::__cxa_demangle(
1289d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung              FName.str().c_str(), nullptr, nullptr, nullptr);
1297f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung          if (!demangled)
1307f8c490e872221221cbfe213c99d1104c483c3a4I-Jui (Ray) Sung            continue;
131bf22a8ab4f46a98ee37f95fc0402744132cc3ed2Yang Ni          const StringRef DemangledNameRef(demangled);
1326749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          DEBUG(dbgs() << "Demangled name: " << DemangledNameRef << '\n');
1336749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1346749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          const StringRef GEAPrefix = "rsGetElementAt_";
1356749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          const StringRef SEAPrefix = "rsSetElementAt_";
1369d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung          const StringRef DIMXPrefix = "rsAllocationGetDimX";
1376749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          assert(GEAPrefix.size() == SEAPrefix.size());
1386749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1396749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          const bool IsGEA = DemangledNameRef.startswith(GEAPrefix);
1406749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          const bool IsSEA = DemangledNameRef.startswith(SEAPrefix);
1419d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung          const bool IsDIMX = DemangledNameRef.startswith(DIMXPrefix);
1426749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1439d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung          assert(IsGEA || IsSEA || IsDIMX);
144c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          if (!A.hasID()) {
145c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung            A.assignID(id_assigned++);
146c2f647a6c790cb1f4c86e50506c53cd912e725f6I-Jui (Ray) Sung          }
1476749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1486749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          if (IsGEA || IsSEA) {
1496749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni            DEBUG(dbgs() << "Found rsAlloc function!\n");
1506749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1516749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni            const auto Kind =
1526749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni                IsGEA ? RSAllocAccessKind::GEA : RSAllocAccessKind::SEA;
1536749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1546749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni            const auto RSElementTy =
1556749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni                DemangledNameRef.drop_front(GEAPrefix.size());
1566749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1576749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni            Calls.push_back({A, FCall, Kind, RSElementTy.str()});
1586749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni            continue;
1596749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          } else if (DemangledNameRef.startswith(GEAPrefix.drop_back()) ||
1606749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni                     DemangledNameRef.startswith(SEAPrefix.drop_back())) {
1616749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni            errs() << "Untyped accesses to global rs_allocations are not "
1626749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni                      "supported.\n";
1636749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni            return false;
1649d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung          } else if (IsDIMX) {
1659d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung            DEBUG(dbgs() << "Found rsAllocationGetDimX function!\n");
1669d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung            const auto Kind = RSAllocAccessKind::DIMX;
1679d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung            Calls.push_back({A, FCall, Kind, ""});
1686749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          }
1696749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni        }
1706749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      }
1716749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1726749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      // TODO: Consider using set-like container to reduce computational
1736749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      // complexity.
1746749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      for (auto *NewU : U->users())
1756749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni        if (std::find(WorkList.begin(), WorkList.end(), NewU) == WorkList.end())
1766749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni          WorkList.push_back(NewU);
1776749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    }
1786749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  }
1796749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
180bf22a8ab4f46a98ee37f95fc0402744132cc3ed2Yang Ni  std::unordered_map<const GlobalVariable *, std::string> GVAccessTypes;
1816749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1826749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  for (auto &Access : Calls) {
1836749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    auto AccessElemTyIt = GVAccessTypes.find(Access.RSAlloc.GlobalVar);
1846749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    if (AccessElemTyIt != GVAccessTypes.end() &&
1856749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni        AccessElemTyIt->second != Access.RSElementTy) {
1866749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      errs() << "Could not infere element type for: ";
1876749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      Access.RSAlloc.GlobalVar->print(errs());
1886749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      errs() << '\n';
1896749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      return false;
1906749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    } else if (AccessElemTyIt == GVAccessTypes.end()) {
1916749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      GVAccessTypes.emplace(Access.RSAlloc.GlobalVar, Access.RSElementTy);
1926749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      Access.RSAlloc.RSElementType = Access.RSElementTy;
1936749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    }
1946749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  }
1956749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1966749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  DEBUG(dbgs() << "\n\n~~~~~~~~~~~~~~~~~~~~~\n\n");
1976749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  return true;
1986749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni}
1996749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
2006749f541c20e86f5deb6fd421ed5849ef43c275cYang Nibool solidifyRSAllocAccess(Module &M, RSAllocationCallInfo CallInfo) {
2019d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  DEBUG(dbgs() << "solidifyRSAllocAccess " << CallInfo.RSAlloc.VarName << '\n');
2026749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  auto *FCall = CallInfo.FCall;
2036749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  auto *Fun = FCall->getCalledFunction();
2046749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  assert(Fun);
2056749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
2069d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  StringRef FName;
2079d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  if (CallInfo.Kind == RSAllocAccessKind::DIMX)
2089d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung    FName = "rsAllocationGetDimX";
2099d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  else
2109d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung    FName = Fun->getName();
211c7b3a43821ccf0f2b13840246e1895744799cf6bYang Ni
2126749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  std::ostringstream OSS;
2139d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  OSS << "__rsov_" << FName.str();
2149d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  // Make up uint32_t F(uint32_t)
2159d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  Type *UInt32Ty = IntegerType::get(M.getContext(), 32);
2169d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  auto *NewFT = FunctionType::get(UInt32Ty, ArrayRef<Type *>(UInt32Ty), false);
2176749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
2189d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  auto *NewF = Function::Create(NewFT, // Fun->getFunctionType(),
2196749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni                                Function::ExternalLinkage, OSS.str(), &M);
2206749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  FCall->setCalledFunction(NewF);
2219d73d08c545462e706ef6951952acff94c37605aI-Jui (Ray) Sung  FCall->setArgOperand(0, ConstantInt::get(UInt32Ty, 0, false));
2226749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  NewF->setAttributes(Fun->getAttributes());
2236749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
2246749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  DEBUG(M.dump());
2256749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
2266749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  return true;
2276749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni}
2286749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
2297974fc03e11f3a8dd40f794f3b33b4889483090cRahul Chaudhry} // namespace rs2spirv
230