For PR411:
[oota-llvm.git] / lib / VMCore / AutoUpgrade.cpp
1 //===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Reid Spencer and is distributed under the 
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the auto-upgrade helper functions 
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Assembly/AutoUpgrade.h"
15 #include "llvm/Function.h"
16 #include "llvm/Type.h"
17 #include <iostream>
18
19 using namespace llvm;
20
21 // UpgradeIntrinsicFunction - Convert overloaded intrinsic function names to
22 // their non-overloaded variants by appending the appropriate suffix based on
23 // the argument types.
24 bool llvm::UpgradeIntrinsicFunction(Function* F) {
25
26   // Get the Function's name.
27   const std::string& Name = F->getName();
28
29   // Quickly eliminate it, if it's not a candidate.
30   if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' || Name[2] !=
31     'v' || Name[3] != 'm' || Name[4] != '.')
32     return false;
33
34   // See if its one of the name's we're interested in.
35   switch (Name[5]) {
36     case 'b':
37       if (Name == "llvm.bswap") {
38         const Type* Ty = F->getReturnType();
39         std::string new_name = Name;
40         if (Ty == Type::UShortTy || Ty == Type::ShortTy)
41           new_name += ".i16";
42         else if (Ty == Type::UIntTy || Ty == Type::IntTy)
43           new_name += ".i32";
44         else if (Ty == Type::ULongTy || Ty == Type::LongTy)
45           new_name += ".i64";
46         std::cerr << "WARNING: change " << Name << " to " 
47           << new_name << "\n";
48         F->setName(new_name);
49         return true;
50       }
51       break;
52     case 'c':
53       if (Name == "llvm.ctpop" || Name == "llvm.ctlz" || 
54           Name == "llvm.cttz") {
55         const Type* Ty = F->getReturnType();
56         std::string new_name = Name;
57         if (Ty == Type::UByteTy || Ty == Type::SByteTy)
58           new_name += ".i8";
59         else if (Ty == Type::UShortTy || Ty == Type::ShortTy)
60           new_name += ".i16";
61         else if (Ty == Type::UIntTy || Ty == Type::IntTy)
62           new_name += ".i32";
63         else if (Ty == Type::ULongTy || Ty == Type::LongTy)
64           new_name += ".i64";
65         std::cerr << "WARNING: change " << Name << " to " 
66           << new_name << "\n";
67         F->setName(new_name);
68         return true;
69       }
70       break;
71     case 'i':
72       if (Name == "llvm.isunordered") {
73         Function::const_arg_iterator ArgIt = F->arg_begin();
74         const Type* Ty = ArgIt->getType();
75         std::string new_name = Name;
76         if (Ty == Type::FloatTy)
77           new_name += ".f32";
78         else if (Ty == Type::DoubleTy)
79           new_name += ".f64";
80         std::cerr << "WARNING: change " << Name << " to " 
81           << new_name << "\n";
82         F->setName(new_name);
83         return true;
84       }
85       break;
86     case 's':
87       if (Name == "llvm.sqrt") {
88         const Type* Ty = F->getReturnType();
89         std::string new_name = Name;
90         if (Ty == Type::FloatTy)
91           new_name += ".f32";
92         else if (Ty == Type::DoubleTy) {
93           new_name += ".f64";
94         }
95         std::cerr << "WARNING: change " << Name << " to " 
96           << new_name << "\n";
97         F->setName(new_name);
98         return true;
99       }
100       break;
101     default:
102       break;
103   }
104   return false;
105 }