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