diff --git a/include/llvm/Assembly/AutoUpgrade.h b/include/llvm/Assembly/AutoUpgrade.h deleted file mode 100644 index 70c29ab66aa..00000000000 --- a/include/llvm/Assembly/AutoUpgrade.h +++ /dev/null @@ -1,61 +0,0 @@ -//===-- llvm/Assembly/AutoUpgrade.h - AutoUpgrade Helpers --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by Reid Spencer is distributed under the University -// of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These functions are implemented by the lib/VMCore/AutoUpgrade.cpp. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ASSEMBLY_AUTOUPGRADE_H -#define LLVM_ASSEMBLY_AUTOUPGRADE_H - -#include -#include - -namespace llvm { - class Function; - class CallInst; - class Instruction; - class Value; - class BasicBlock; - - /// This function inspects the Function \p F to see if it is an old overloaded - /// intrinsic. If it is, the Function's name is changed to add a suffix that - /// indicates the kind of arguments or result that it accepts. In LLVM release - /// 1.7, the overloading of intrinsic functions was replaced with separate - /// functions for each of the various argument sizes. This function implements - /// the auto-upgrade feature from the old overloaded names to the new - /// non-overloaded names. - /// @param F The Function to potentially auto-upgrade. - /// @returns A corrected version of F, or 0 if no change necessary - /// @brief Remove overloaded intrinsic function names. - Function* UpgradeIntrinsicFunction(Function* F); - - /// In LLVM 1.7, the overloading of intrinsic functions was replaced with - /// separate functions for each of the various argument sizes. This function - /// implements the auto-upgrade feature from old overloaded names to the new - /// non-overloaded names. This function inspects the CallInst \p CI to see - /// if it is a call to an old overloaded intrinsic. If it is, a new CallInst - /// is created that uses the correct Function and possibly casts the - /// argument and result to an unsigned type. - /// @brief Get replacement instruction for overloaded intrinsic function call. - void UpgradeIntrinsicCall( - CallInst* CI, ///< The CallInst to potentially auto-upgrade. - Function* newF = 0 ///< The new function for the call replacement. - ); - - /// Upgrade both the function and all the calls made to it, if that function - /// needs to be upgraded. This is like a combination of the above two - /// functions, UpgradeIntrinsicFunction and UpgradeIntrinsicCall. Note that - /// the calls are replaced so this should only be used in a post-processing - /// manner (i.e. after all assembly/bytecode has been read). - bool UpgradeCallsToIntrinsic(Function* F); - -} // End llvm namespace - -#endif diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp deleted file mode 100644 index 9f7f818e7ff..00000000000 --- a/lib/VMCore/AutoUpgrade.cpp +++ /dev/null @@ -1,287 +0,0 @@ -//===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by Reid Spencer and is distributed under the -// University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the auto-upgrade helper functions -// -//===----------------------------------------------------------------------===// - -#include "llvm/Assembly/AutoUpgrade.h" -#include "llvm/Support/Streams.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/Module.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" -#include "llvm/SymbolTable.h" -using namespace llvm; - -static Function *getUpgradedUnaryFn(Function *F) { - const std::string &Name = F->getName(); - Module *M = F->getParent(); - switch (F->getReturnType()->getTypeID()) { - default: return 0; - case Type::UByteTyID: - case Type::SByteTyID: - return M->getOrInsertFunction(Name+".i8", - Type::UByteTy, Type::UByteTy, NULL); - case Type::UShortTyID: - case Type::ShortTyID: - return M->getOrInsertFunction(Name+".i16", - Type::UShortTy, Type::UShortTy, NULL); - case Type::UIntTyID: - case Type::IntTyID: - return M->getOrInsertFunction(Name+".i32", - Type::UIntTy, Type::UIntTy, NULL); - case Type::ULongTyID: - case Type::LongTyID: - return M->getOrInsertFunction(Name+".i64", - Type::ULongTy, Type::ULongTy, NULL); - case Type::FloatTyID: - return M->getOrInsertFunction(Name+".f32", - Type::FloatTy, Type::FloatTy, NULL); - case Type::DoubleTyID: - return M->getOrInsertFunction(Name+".f64", - Type::DoubleTy, Type::DoubleTy, NULL); - } -} - -static Function *getUpgradedIntrinsic(Function *F) { - // If there's no function, we can't get the argument type. - if (!F) return 0; - - // Get the Function's name. - const std::string& Name = F->getName(); - - // Quickly eliminate it, if it's not a candidate. - if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || - Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.') - return 0; - - Module *M = F->getParent(); - switch (Name[5]) { - default: break; - case 'b': - if (Name == "llvm.bswap") return getUpgradedUnaryFn(F); - break; - case 'c': - if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || Name == "llvm.cttz") - return getUpgradedUnaryFn(F); - break; - case 'd': - if (Name == "llvm.dbg.stoppoint") { - PointerType *ESP = - PointerType::get(StructType::get(std::vector())); - if (F->getReturnType() != Type::VoidTy || - F->getFunctionType()->getParamType(2) != ESP) { - return M->getOrInsertFunction(Name, Type::VoidTy, - Type::UIntTy, Type::UIntTy, ESP, NULL); - } - } else if (Name == "llvm.dbg.func.start") { - PointerType *ESP = - PointerType::get(StructType::get(std::vector())); - if (F->getReturnType() != Type::VoidTy || - F->getFunctionType()->getParamType(0) != ESP) { - return M->getOrInsertFunction(Name, Type::VoidTy, ESP, NULL); - } - } else if (Name == "llvm.dbg.region.start") { - PointerType *ESP = - PointerType::get(StructType::get(std::vector())); - if (F->getReturnType() != Type::VoidTy || - F->getFunctionType()->getParamType(0) != ESP) { - return M->getOrInsertFunction(Name, Type::VoidTy, ESP, NULL); - } - } else if (Name == "llvm.dbg.region.end") { - PointerType *ESP = - PointerType::get(StructType::get(std::vector())); - if (F->getReturnType() != Type::VoidTy || - F->getFunctionType()->getParamType(0) != ESP) { - return M->getOrInsertFunction(Name, Type::VoidTy, ESP, NULL); - } - } else if (Name == "llvm.dbg.declare") { - PointerType *ESP = - PointerType::get(StructType::get(std::vector())); - if (F->getReturnType() != Type::VoidTy || - F->getFunctionType()->getParamType(0) != ESP || - F->getFunctionType()->getParamType(1) != ESP) { - return M->getOrInsertFunction(Name, Type::VoidTy, ESP, ESP, NULL); - } - } - break; - case 'i': - if (Name == "llvm.isunordered" && F->arg_begin() != F->arg_end()) { - if (F->arg_begin()->getType() == Type::FloatTy) - return M->getOrInsertFunction(Name+".f32", F->getFunctionType()); - if (F->arg_begin()->getType() == Type::DoubleTy) - return M->getOrInsertFunction(Name+".f64", F->getFunctionType()); - } - break; - case 'm': - if (Name == "llvm.memcpy" || Name == "llvm.memset" || - Name == "llvm.memmove") { - if (F->getFunctionType()->getParamType(2) == Type::UIntTy || - F->getFunctionType()->getParamType(2) == Type::IntTy) - return M->getOrInsertFunction(Name+".i32", Type::VoidTy, - PointerType::get(Type::SByteTy), - F->getFunctionType()->getParamType(1), - Type::UIntTy, Type::UIntTy, NULL); - if (F->getFunctionType()->getParamType(2) == Type::ULongTy || - F->getFunctionType()->getParamType(2) == Type::LongTy) - return M->getOrInsertFunction(Name+".i64", Type::VoidTy, - PointerType::get(Type::SByteTy), - F->getFunctionType()->getParamType(1), - Type::ULongTy, Type::UIntTy, NULL); - } - break; - case 's': - if (Name == "llvm.sqrt") - return getUpgradedUnaryFn(F); - break; - } - return 0; -} - -// Occasionally upgraded function call site arguments need to be permutated to -// some new order. The result of getArgumentPermutation is an array of size -// F->getFunctionType()getNumParams() indicating the new operand order. A value -// of zero in the array indicates replacing with UndefValue for the arg type. -// NULL is returned if there is no permutation. It's assumed that the function -// name is in the form "llvm.?????" -static unsigned *getArgumentPermutation(Function* Fn, Function* NewFn) { - const std::string& Name = Fn->getName(); - unsigned N = Fn->getFunctionType()->getNumParams(); - unsigned M = NewFn->getFunctionType()->getNumParams(); - - switch (Name[5]) { - case 'd': - if (Name == "llvm.dbg.stoppoint") { - static unsigned Permutation[] = { 2, 3, 4 }; - assert(M == (sizeof(Permutation) / sizeof(unsigned)) && - "Permutation is wrong length"); - if (N == 4) return Permutation; - } else if (Name == "llvm.dbg.region.start") { - static unsigned Permutation[] = { 0 }; - assert(M == (sizeof(Permutation) / sizeof(unsigned)) && - "Permutation is wrong length"); - if (N == 0) return Permutation; - } else if (Name == "llvm.dbg.region.end") { - static unsigned Permutation[] = { 0 }; - assert(M == (sizeof(Permutation) / sizeof(unsigned)) && - "Permutation is wrong length"); - if (N == 0) return Permutation; - } else if (Name == "llvm.dbg.declare") { - static unsigned Permutation[] = { 0, 0 }; - assert(M == (sizeof(Permutation) / sizeof(unsigned)) && - "Permutation is wrong length"); - if (N == 0) return Permutation; - } - break; - } - return NULL; -} - -// UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to -// their non-overloaded variants by appending the appropriate suffix based on -// the argument types. -Function *llvm::UpgradeIntrinsicFunction(Function* F) { - // See if its one of the name's we're interested in. - if (Function *R = getUpgradedIntrinsic(F)) { - if (R->getName() != F->getName()) - llvm_cerr << "WARNING: change " << F->getName() << " to " - << R->getName() << "\n"; - return R; - } - return 0; -} - -// CastArg - Perform the appropriate cast of an upgraded argument. -// -static Value *CastArg(Value *Arg, const Type *Ty, Instruction *InsertBefore) { - if (Constant *C = dyn_cast(Arg)) { - return ConstantExpr::getCast(C, Ty); - } else { - return CastInst::createInferredCast(Arg, Ty, "autoupgrade_cast", - InsertBefore); - } -} - -// UpgradeIntrinsicCall - In the BC reader, change a call to an intrinsic to be -// a call to an upgraded intrinsic. We may have to permute the order or promote -// some arguments with a cast. -void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { - Function *F = CI->getCalledFunction(); - - const FunctionType *NewFnTy = NewFn->getFunctionType(); - std::vector Oprnds; - - unsigned *Permutation = getArgumentPermutation(F, NewFn); - unsigned N = NewFnTy->getNumParams(); - - if (Permutation) { - for (unsigned i = 0; i != N; ++i) { - unsigned p = Permutation[i]; - - if (p) { - Value *V = CI->getOperand(p); - if (V->getType() != NewFnTy->getParamType(i)) - V = CastArg(V, NewFnTy->getParamType(i), CI); - Oprnds.push_back(V); - } else - Oprnds.push_back(UndefValue::get(NewFnTy->getParamType(i))); - } - } else if (N) { - assert(N == (CI->getNumOperands() - 1) && - "Upgraded function needs permutation"); - for (unsigned i = 0; i != N; ++i) { - Value *V = CI->getOperand(i + 1); - if (V->getType() != NewFnTy->getParamType(i)) - V = CastArg(V, NewFnTy->getParamType(i), CI); - Oprnds.push_back(V); - } - } - - bool NewIsVoid = NewFn->getReturnType() == Type::VoidTy; - - CallInst *NewCI = new CallInst(NewFn, Oprnds, - NewIsVoid ? "" : CI->getName(), - CI); - NewCI->setTailCall(CI->isTailCall()); - NewCI->setCallingConv(CI->getCallingConv()); - - if (!CI->use_empty()) { - if (NewIsVoid) { - CI->replaceAllUsesWith(UndefValue::get(CI->getType())); - } else { - Instruction *RetVal = NewCI; - - if (F->getReturnType() != NewFn->getReturnType()) { - RetVal = - new BitCastInst(NewCI, F->getReturnType(), NewCI->getName(), CI); - NewCI->moveBefore(RetVal); - } - - CI->replaceAllUsesWith(RetVal); - } - } - CI->eraseFromParent(); -} - -bool llvm::UpgradeCallsToIntrinsic(Function* F) { - if (Function* NewFn = UpgradeIntrinsicFunction(F)) { - for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); - UI != UE; ) { - if (CallInst* CI = dyn_cast(*UI++)) - UpgradeIntrinsicCall(CI, NewFn); - } - if (NewFn != F) - F->eraseFromParent(); - return true; - } - return false; -}