AutoUpgrade.cpp revision bf47c7627812714b9427c7c847d6880194a76af6
16994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
26994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//
36994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//                     The LLVM Compiler Infrastructure
46994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
76994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//
86994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//===----------------------------------------------------------------------===//
96994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//
106994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// This file implements the auto-upgrade helper functions
116994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//
126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//===----------------------------------------------------------------------===//
136994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth
146994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth#include "llvm/AutoUpgrade.h"
15d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson#include "llvm/Constants.h"
166994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth#include "llvm/Function.h"
17c82a61c6c611857e47c3d6c6dbd069c27cd6d0f2Bill Wendling#include "llvm/Instruction.h"
18f81b57694b3c34a79b1464ffd21e6768c8d22662Owen Anderson#include "llvm/LLVMContext.h"
196994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth#include "llvm/Module.h"
20e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel#include "llvm/IntrinsicInst.h"
21c82a61c6c611857e47c3d6c6dbd069c27cd6d0f2Bill Wendling#include "llvm/ADT/DenseMap.h"
22c82a61c6c611857e47c3d6c6dbd069c27cd6d0f2Bill Wendling#include "llvm/ADT/SmallPtrSet.h"
2358d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner#include "llvm/ADT/SmallVector.h"
24bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif#include "llvm/Support/CallSite.h"
25c82a61c6c611857e47c3d6c6dbd069c27cd6d0f2Bill Wendling#include "llvm/Support/CFG.h"
26c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
276d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher#include "llvm/Support/IRBuilder.h"
28ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstring>
296994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthusing namespace llvm;
306994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth
316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth
32f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Chengstatic bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
336994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  assert(F && "Illegal to upgrade a non-existent Function.");
346994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth
356994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  // Quickly eliminate it, if it's not a candidate.
36747fddd48450d75794c4f58c020f54785b4bc66fChris Lattner  StringRef Name = F->getName();
37747fddd48450d75794c4f58c020f54785b4bc66fChris Lattner  if (Name.size() <= 8 || !Name.startswith("llvm."))
38f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng    return false;
39747fddd48450d75794c4f58c020f54785b4bc66fChris Lattner  Name = Name.substr(5); // Strip off "llvm."
40b5dd9de7240f3018dcd8ce84c158547a5e0f1131Chris Lattner
41747fddd48450d75794c4f58c020f54785b4bc66fChris Lattner  switch (Name[0]) {
426994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  default: break;
43ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth  case 'c': {
44ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    if (Name.startswith("ctlz.") && F->arg_size() == 1) {
45ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth      F->setName(Name + ".old");
46a56f5581ecb6ba741645a74bfa399f4bdf5b2f71Chandler Carruth      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz,
47a56f5581ecb6ba741645a74bfa399f4bdf5b2f71Chandler Carruth                                        F->arg_begin()->getType());
48ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth      return true;
49ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    }
50ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    if (Name.startswith("cttz.") && F->arg_size() == 1) {
51ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth      F->setName(Name + ".old");
52a56f5581ecb6ba741645a74bfa399f4bdf5b2f71Chandler Carruth      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::cttz,
53a56f5581ecb6ba741645a74bfa399f4bdf5b2f71Chandler Carruth                                        F->arg_begin()->getType());
54ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth      return true;
55ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    }
56ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    break;
57ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth  }
58747fddd48450d75794c4f58c020f54785b4bc66fChris Lattner  }
596994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth
606994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  //  This may not belong here. This function is effectively being overloaded
616994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  //  to both detect an intrinsic which needs upgrading, and to provide the
626994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  //  upgraded form of the intrinsic. We should perhaps have two separate
636994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  //  functions for this.
64f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng  return false;
656994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth}
666994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth
67f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Chengbool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) {
68f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng  NewFn = 0;
69f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng  bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn);
70a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands
71a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands  // Upgrade intrinsic attributes.  This does not change the function.
72f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng  if (NewFn)
73f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng    F = NewFn;
7449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen  if (unsigned id = F->getIntrinsicID())
750598866c052147c31b808391f58434ce3dbfb838Devang Patel    F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id));
76a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands  return Upgraded;
77a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands}
78a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands
79de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendlingbool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {
80b85e4eba85a38698f3b3332f82554bf8442547e2Chris Lattner  // Nothing to do yet.
81de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling  return false;
82de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling}
83de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling
846994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
856994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// upgraded intrinsic. All argument and return casting must be provided in
866994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// order to seamlessly integrate with existing context.
876994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthvoid llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
88bf47c7627812714b9427c7c847d6880194a76af6Nick Lewycky  assert(CI->getCalledFunction() && "Intrinsic call is not direct?");
89ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth  if (!NewFn) return;
90ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth
91bf47c7627812714b9427c7c847d6880194a76af6Nick Lewycky  LLVMContext &C = CI->getContext();
92ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth  IRBuilder<> Builder(C);
93ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth  Builder.SetInsertPoint(CI->getParent(), CI);
94ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth
95ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth  switch (NewFn->getIntrinsicID()) {
96ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth  default:
97b5dd9de7240f3018dcd8ce84c158547a5e0f1131Chris Lattner    llvm_unreachable("Unknown function for CallInst upgrade.");
98ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth
99ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth  case Intrinsic::ctlz:
100ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth  case Intrinsic::cttz:
101ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    assert(CI->getNumArgOperands() == 1 &&
102ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth           "Mismatch between function args and call args");
103ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    StringRef Name = CI->getName();
104ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    CI->setName(Name + ".old");
105ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    CI->replaceAllUsesWith(Builder.CreateCall2(NewFn, CI->getArgOperand(0),
106ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth                                               Builder.getFalse(), Name));
107ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    CI->eraseFromParent();
108ccbf1e36d34c2d66600748bdd8767dc122629a58Chandler Carruth    return;
109f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng  }
1106994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth}
1116994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth
1126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// This tests each Function to determine if it needs upgrading. When we find
1136994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// one we are interested in, we then upgrade all calls to reflect the new
1146994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// function.
1156994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthvoid llvm::UpgradeCallsToIntrinsic(Function* F) {
1166994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  assert(F && "Illegal attempt to upgrade a non-existent intrinsic.");
1176994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth
1186994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  // Upgrade the function and check if it is a totaly new function.
119b85e4eba85a38698f3b3332f82554bf8442547e2Chris Lattner  Function *NewFn;
120f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng  if (UpgradeIntrinsicFunction(F, NewFn)) {
1216994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth    if (NewFn != F) {
1226994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth      // Replace all uses to the old function with the new one if necessary.
1236994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth      for (Value::use_iterator UI = F->use_begin(), UE = F->use_end();
1246994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth           UI != UE; ) {
125b85e4eba85a38698f3b3332f82554bf8442547e2Chris Lattner        if (CallInst *CI = dyn_cast<CallInst>(*UI++))
1266994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth          UpgradeIntrinsicCall(CI, NewFn);
1276994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth      }
1286994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth      // Remove old function, no longer used, from the module.
1296994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth      F->eraseFromParent();
1306994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth    }
1316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth  }
1326994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth}
133e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel
134