diff --git a/include/llvm/Assembly/AutoUpgrade.h b/include/llvm/Assembly/AutoUpgrade.h new file mode 100644 index 00000000000..fbbc7b5e8e3 --- /dev/null +++ b/include/llvm/Assembly/AutoUpgrade.h @@ -0,0 +1,33 @@ +//===-- 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 + +namespace llvm { + class Function; + + /// 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. + /// @brief Remove overloaded intrinsic function names. + bool UpgradeIntrinsicFunction(Function* F); + +} // End llvm namespace + +#endif diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp new file mode 100644 index 00000000000..46794256c27 --- /dev/null +++ b/lib/VMCore/AutoUpgrade.cpp @@ -0,0 +1,105 @@ +//===-- 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/Function.h" +#include "llvm/Type.h" +#include + +using namespace llvm; + +// UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to +// their non-overloaded variants by appending the appropriate suffix based on +// the argument types. +bool llvm::UpgradeIntrinsicFunction(Function* F) { + + // Get the Function's name. + const std::string& Name = F->getName(); + + // Quickly eliminate it, if it's not a candidate. + if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' || Name[2] != + 'v' || Name[3] != 'm' || Name[4] != '.') + return false; + + // See if its one of the name's we're interested in. + switch (Name[5]) { + case 'b': + if (Name == "llvm.bswap") { + const Type* Ty = F->getReturnType(); + std::string new_name = Name; + if (Ty == Type::UShortTy || Ty == Type::ShortTy) + new_name += ".i16"; + else if (Ty == Type::UIntTy || Ty == Type::IntTy) + new_name += ".i32"; + else if (Ty == Type::ULongTy || Ty == Type::LongTy) + new_name += ".i64"; + std::cerr << "WARNING: change " << Name << " to " + << new_name << "\n"; + F->setName(new_name); + return true; + } + break; + case 'c': + if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || + Name == "llvm.cttz") { + const Type* Ty = F->getReturnType(); + std::string new_name = Name; + if (Ty == Type::UByteTy || Ty == Type::SByteTy) + new_name += ".i8"; + else if (Ty == Type::UShortTy || Ty == Type::ShortTy) + new_name += ".i16"; + else if (Ty == Type::UIntTy || Ty == Type::IntTy) + new_name += ".i32"; + else if (Ty == Type::ULongTy || Ty == Type::LongTy) + new_name += ".i64"; + std::cerr << "WARNING: change " << Name << " to " + << new_name << "\n"; + F->setName(new_name); + return true; + } + break; + case 'i': + if (Name == "llvm.isunordered") { + Function::const_arg_iterator ArgIt = F->arg_begin(); + const Type* Ty = ArgIt->getType(); + std::string new_name = Name; + if (Ty == Type::FloatTy) + new_name += ".f32"; + else if (Ty == Type::DoubleTy) + new_name += ".f64"; + std::cerr << "WARNING: change " << Name << " to " + << new_name << "\n"; + F->setName(new_name); + return true; + } + break; + case 's': + if (Name == "llvm.sqrt") { + const Type* Ty = F->getReturnType(); + std::string new_name = Name; + if (Ty == Type::FloatTy) + new_name += ".f32"; + else if (Ty == Type::DoubleTy) { + new_name += ".f64"; + } + std::cerr << "WARNING: change " << Name << " to " + << new_name << "\n"; + F->setName(new_name); + return true; + } + break; + default: + break; + } + return false; +}