Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(476)

Side by Side Diff: llvm/lib/CodeGen/IntrinsicLowering.cpp

Issue 8439026: Get rid of libgcc and nacl_read_tp symbol preservation hacks. (Closed) Base URL: http://code.google.com/p/nacl-llvm-branches.upstream
Patch Set: missing localmod marker Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// 1 //===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the IntrinsicLowering class. 10 // This file implements the IntrinsicLowering class.
11 // 11 //
12 //===----------------------------------------------------------------------===// 12 //===----------------------------------------------------------------------===//
13 13
14 #include "llvm/Constants.h" 14 #include "llvm/Constants.h"
15 #include "llvm/DerivedTypes.h" 15 #include "llvm/DerivedTypes.h"
16 #include "llvm/Module.h" 16 #include "llvm/Module.h"
17 #include "llvm/Type.h" 17 #include "llvm/Type.h"
18 #include "llvm/CodeGen/IntrinsicLowering.h" 18 #include "llvm/CodeGen/IntrinsicLowering.h"
19 #include "llvm/Support/CallSite.h" 19 #include "llvm/Support/CallSite.h"
20 #include "llvm/Support/CommandLine.h" // @LOCALMOD
21 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/IRBuilder.h" 21 #include "llvm/Support/IRBuilder.h"
23 #include "llvm/Support/raw_ostream.h" 22 #include "llvm/Support/raw_ostream.h"
24 #include "llvm/Target/TargetData.h" 23 #include "llvm/Target/TargetData.h"
25 #include "llvm/ADT/SmallVector.h" 24 #include "llvm/ADT/SmallVector.h"
26 using namespace llvm; 25 using namespace llvm;
27 26
28 // @LOCALMOD-BEGIN
29 static cl::opt<bool>
30 AddNaClReadTPDep("add-nacl-read-tp-dependency",
31 cl::desc("Add __nacl_read_tp dependency to bitcode modules"),
32 cl::init(false));
33
34 // We use this when we want to link libgcc as bitcode
35 static cl::opt<bool>
36 AddLibgccDeps("add-libgcc-dependencies",
37 cl::desc("Add libgcc dependencies to bitcode modules"),
38 cl::init(false));
39 // @LOCALMOD-END
40
41 template <class ArgIt> 27 template <class ArgIt>
42 static void EnsureFunctionExists(Module &M, const char *Name, 28 static void EnsureFunctionExists(Module &M, const char *Name,
43 ArgIt ArgBegin, ArgIt ArgEnd, 29 ArgIt ArgBegin, ArgIt ArgEnd,
44 Type *RetTy) { 30 Type *RetTy) {
45 // Insert a correctly-typed definition now. 31 // Insert a correctly-typed definition now.
46 std::vector<Type *> ParamTys; 32 std::vector<Type *> ParamTys;
47 for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 33 for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
48 ParamTys.push_back(I->getType()); 34 ParamTys.push_back(I->getType());
49 M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); 35 M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false));
50 } 36 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 86
101 // VisualStudio defines setjmp as _setjmp 87 // VisualStudio defines setjmp as _setjmp
102 #if defined(_MSC_VER) && defined(setjmp) && \ 88 #if defined(_MSC_VER) && defined(setjmp) && \
103 !defined(setjmp_undefined_for_msvc) 89 !defined(setjmp_undefined_for_msvc)
104 # pragma push_macro("setjmp") 90 # pragma push_macro("setjmp")
105 # undef setjmp 91 # undef setjmp
106 # define setjmp_undefined_for_msvc 92 # define setjmp_undefined_for_msvc
107 #endif 93 #endif
108 94
109 // @LOCALMOD-BEGIN 95 // @LOCALMOD-BEGIN
110 // NOTE: we are experimenting with the idea of providing libgcc
111 // in a bitcode (derived) form. If this works out libgcc will not
112 // differ between platforms anymore, and the list of symbols below will
113 // be what is guaranteed to be included with libgcc.
114 // If for some reason a backend needs additional functions
115 // it would have generated them itself.
116 // NOTE: llvm bitcode does not preserve signedness of types so the type
117 // annotation below is simplified:
118 // s: i32
119 // d: i64
120 // f: f32
121 // F: f64
122 // The first letter denotes the return type the remaining one the
123 // parameter types.
124 static const struct { const char* name; const char* types; }
125 LibgccIntrinsicNames[] = {
126 /* RTLIB::SDIV_I32 */ {"__divsi3", "sss"},
127 /* RTLIB::SDIV_I64 */ {"__divdi3", "ddd"},
128
129 /* RTLIB::UDIV_I32 */ {"__udivsi3", "sss"},
130 /* RTLIB::UDIV_I64 */ {"__udivdi3", "ddd"},
131
132 /* RTLIB::SREM_I32 */ {"__modsi3", "sss"},
133 /* RTLIB::SREM_I64 */ {"__moddi3", "ddd"},
134
135 /* RTLIB::UREM_I32 */ {"__umodsi3", "sss"},
136 /* RTLIB::UREM_I64 */ {"__umoddi3", "ddd"},
137
138 /* RTLIB::FPTOSINT_F32_I32 */ {"__fixsfsi", "sf"},
139 /* RTLIB::FPTOSINT_F32_I64 */ {"__fixsfdi", "df"},
140
141 /* RTLIB::FPTOSINT_F64_I32 */ {"__fixdfsi", "sF"},
142 /* RTLIB::FPTOSINT_F64_I64 */ {"__fixdfdi", "dF"},
143
144 /* RTLIB::FPTOUINT_F32_I32 */ {"__fixunssfsi", "sf"},
145 /* RTLIB::FPTOUINT_F32_I64 */ {"__fixunssfdi", "dF"},
146
147 /* RTLIB::FPTOUINT_F64_I32 */ {"__fixunsdfsi", "sF"},
148 /* RTLIB::FPTOUINT_F64_I64 */ {"__fixunsdfdi", "dF"},
149
150 /* RTLIB::SINTTOFP_I32_F32 */ {"__floatsisf", "fs"},
151 /* RTLIB::SINTTOFP_I32_F64 */ {"__floatsidf", "Fs"},
152
153 /* RTLIB::SINTTOFP_I64_F32 */ {"__floatdisf", "fd"},
154 /* RTLIB::SINTTOFP_I64_F64 */ {"__floatdidf", "Fd"},
155
156 /* RTLIB::UINTTOFP_I32_F32 */ {"__floatunsisf", "fs"},
157 /* RTLIB::UINTTOFP_I32_F64 */ {"__floatunsidf", "Fs"},
158
159 /* RTLIB::UINTTOFP_I64_F32 */ {"__floatundisf", "fd"},
160 /* RTLIB::UINTTOFP_I64_F64 */ {"__floatundidf", "Fd"},
161
162 /* RTLIB::POWI_F32 */ {"__powisf2", "ffs"},
163 /* RTLIB::POWI_F64 */ {"__powidf2", "FFs"},
164 {NULL, NULL}
165 };
166
167 // Calls to these functions may materialize as part of a conversion 96 // Calls to these functions may materialize as part of a conversion
168 // from an intrinsics, e.g. llvm.memset -> memset 97 // from an intrinsics, e.g. llvm.memset -> memset
169 // So if these functions are available in bitcode form we need to: 98 // So if these functions are available in bitcode form we need to:
170 // * make sure they do not get discarded -- if there is a chance that 99 // * make sure they do not get discarded -- if there is a chance that
171 // a caller might materialize 100 // a caller might materialize
172 // * make sure they do not get specialized for a given callsite 101 // * make sure they do not get specialized for a given callsite
173 // Both problems are avoided by pretending there are unknown callers. 102 // Both problems are avoided by pretending there are unknown callers.
174 // The function: IntrinsicLowering::AddPrototypes() below does just that. 103 // The function: IntrinsicLowering::AddPrototypes() below does just that.
175 // TODO(robertm): elaborate some more 104 // TODO(robertm): elaborate some more
176 static const char *MiscIntrinsicNames[] = { 105 static const char *IntrinsicNames[] = {
177 "abort", 106 "abort",
178 "memcpy", "memset", "memmove", 107 "memcpy", "memset", "memmove",
179 "sqrtf", "sqrt", "sqrtl", 108 "sqrtf", "sqrt", "sqrtl",
180 "sinf", "sin", "sinl", 109 "sinf", "sin", "sinl",
181 "cosf", "cos", "cosl", 110 "cosf", "cos", "cosl",
182 "powf", "pow", "powl", 111 "powf", "pow", "powl",
183 "logf", "log", "logl", 112 "logf", "log", "logl",
184 "log2f", "log2", "log2l", 113 "log2f", "log2", "log2l",
185 "log10f", "log10", "log10l", 114 "log10f", "log10", "log10l",
186 "expf", "exp", "expl", 115 "expf", "exp", "expl",
187 "exp2f", "exp2", "exp2l", 116 "exp2f", "exp2", "exp2l",
188 "__nacl_read_tp",
189 NULL 117 NULL
190 }; 118 };
191 119
192 StringSet<> IntrinsicLowering::FuncNames; 120 StringSet<> IntrinsicLowering::FuncNames;
193 121
194 const StringSet<> &IntrinsicLowering::GetFuncNames() { 122 const StringSet<> &IntrinsicLowering::GetFuncNames() {
195 if (FuncNames.empty()) { 123 if (FuncNames.empty()) {
196 for (unsigned i=0; MiscIntrinsicNames[i]; ++i) 124 for (unsigned i=0; IntrinsicNames[i]; ++i)
197 FuncNames.insert(MiscIntrinsicNames[i]); 125 FuncNames.insert(IntrinsicNames[i]);
198
199 for (unsigned i=0; LibgccIntrinsicNames[i].name; ++i)
200 FuncNames.insert(LibgccIntrinsicNames[i].name);
201 } 126 }
202 return FuncNames; 127 return FuncNames;
203 } 128 }
204 129
205 bool IntrinsicLowering::IsCalledByIntrinsic(const StringRef &FuncName) { 130 bool IntrinsicLowering::IsCalledByIntrinsic(const StringRef &FuncName) {
206 return IntrinsicLowering::GetFuncNames().count(FuncName) > 0; 131 return IntrinsicLowering::GetFuncNames().count(FuncName) > 0;
207 } 132 }
208 // @LOCALMOD-END 133 // @LOCALMOD-END
209 134
210 void IntrinsicLowering::AddPrototypes(Module &M) { 135 void IntrinsicLowering::AddPrototypes(Module &M) {
211 LLVMContext &Context = M.getContext(); 136 LLVMContext &Context = M.getContext();
212
213 // @LOCALMOD-BEGIN
214 // Calls to __nacl_read_tp may be generated by codegen on X86-64
215 // in non-PIC TLS mode. Since __nacl_read_tp exists in a bitcode
216 // archive, it is necessary to add a dependency to it during
217 // bitcode linking, so that it gets included in the link.
218 if (AddNaClReadTPDep) {
219 Type *RetTy = Type::getInt8PtrTy(Context);
220 M.getOrInsertFunction("__nacl_read_tp", RetTy, (Type*)0);
221 }
222
223 // If we link libgcc we need to add a dependency to all its functions
224 // during bitcode linking, so that they get included in the link.
225
226 if (AddLibgccDeps) {
227 Type *CharToTypeMap[128];
228 for (unsigned i=0; i < 128; ++i) {
229 CharToTypeMap[i] = 0;
230 }
231 CharToTypeMap['f'] = Type::getFloatTy(Context);
232 CharToTypeMap['F'] = Type::getDoubleTy(Context);
233 CharToTypeMap['s'] = Type::getInt32Ty(Context);
234 CharToTypeMap['d'] = Type::getInt64Ty(Context);
235
236 for (unsigned i=0; LibgccIntrinsicNames[i].name; ++i) {
237 Type *RetTy = 0;
238 std::vector<Type *> ParamTys;
239 const char* name = LibgccIntrinsicNames[i].name;
240 const char* params = LibgccIntrinsicNames[i].types;
241 for (unsigned j=0; params[j]; ++j) {
242 Type *Current = CharToTypeMap[params[j]];
243 assert (Current != 0);
244 if (j == 0) {
245 RetTy = Current;
246 } else {
247 ParamTys.push_back(Current);
248 }
249 }
250 M.getOrInsertFunction(name, FunctionType::get(RetTy,
251 makeArrayRef(ParamTys),
252 false));
253 }
254 }
255 // @LOCALMOD-END
256
257 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 137 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
258 if (I->isDeclaration() && !I->use_empty()) 138 if (I->isDeclaration() && !I->use_empty())
259 switch (I->getIntrinsicID()) { 139 switch (I->getIntrinsicID()) {
260 default: break; 140 default: break;
261 case Intrinsic::setjmp: 141 case Intrinsic::setjmp:
262 EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(), 142 EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(),
263 Type::getInt32Ty(M.getContext())); 143 Type::getInt32Ty(M.getContext()));
264 break; 144 break;
265 case Intrinsic::longjmp: 145 case Intrinsic::longjmp:
266 EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(), 146 EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(),
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 Module *M = CI->getParent()->getParent()->getParent(); 601 Module *M = CI->getParent()->getParent()->getParent();
722 Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty); 602 Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty);
723 603
724 Value *Op = CI->getArgOperand(0); 604 Value *Op = CI->getArgOperand(0);
725 Op = CallInst::Create(Int, Op, CI->getName(), CI); 605 Op = CallInst::Create(Int, Op, CI->getName(), CI);
726 606
727 CI->replaceAllUsesWith(Op); 607 CI->replaceAllUsesWith(Op);
728 CI->eraseFromParent(); 608 CI->eraseFromParent();
729 return true; 609 return true;
730 } 610 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698