14
14
#include " llvm/IR/Instruction.h"
15
15
#include " llvm/IR/IntrinsicInst.h"
16
16
#include " llvm/IR/Instructions.h"
17
+ #include " llvm/Support/CallSite.h"
17
18
#include " llvm/Support/ErrorHandling.h"
18
19
19
20
using namespace llvm ;
@@ -58,10 +59,39 @@ unsigned TargetTransformInfo::getGEPCost(
58
59
return PrevTTI->getGEPCost (Ptr , Operands);
59
60
}
60
61
62
+ unsigned TargetTransformInfo::getCallCost (FunctionType *FTy,
63
+ int NumArgs) const {
64
+ return PrevTTI->getCallCost (FTy, NumArgs);
65
+ }
66
+
67
+ unsigned TargetTransformInfo::getCallCost (const Function *F,
68
+ int NumArgs) const {
69
+ return PrevTTI->getCallCost (F, NumArgs);
70
+ }
71
+
72
+ unsigned TargetTransformInfo::getCallCost (
73
+ const Function *F, ArrayRef<const Value *> Arguments) const {
74
+ return PrevTTI->getCallCost (F, Arguments);
75
+ }
76
+
77
+ unsigned TargetTransformInfo::getIntrinsicCost (
78
+ Intrinsic::ID IID, Type *RetTy, ArrayRef<Type *> ParamTys) const {
79
+ return PrevTTI->getIntrinsicCost (IID, RetTy, ParamTys);
80
+ }
81
+
82
+ unsigned TargetTransformInfo::getIntrinsicCost (
83
+ Intrinsic::ID IID, Type *RetTy, ArrayRef<const Value *> Arguments) const {
84
+ return PrevTTI->getIntrinsicCost (IID, RetTy, Arguments);
85
+ }
86
+
61
87
unsigned TargetTransformInfo::getUserCost (const User *U) const {
62
88
return PrevTTI->getUserCost (U);
63
89
}
64
90
91
+ bool TargetTransformInfo::isLoweredToCall (const Function *F) const {
92
+ return PrevTTI->isLoweredToCall (F);
93
+ }
94
+
65
95
bool TargetTransformInfo::isLegalAddImmediate (int64_t Imm) const {
66
96
return PrevTTI->isLegalAddImmediate (Imm);
67
97
}
@@ -179,6 +209,7 @@ struct NoTTI : ImmutablePass, TargetTransformInfo {
179
209
virtual void initializePass () {
180
210
// Note that this subclass is special, and must *not* call initializeTTI as
181
211
// it does not chain.
212
+ TopTTI = this ;
182
213
PrevTTI = 0 ;
183
214
DL = getAnalysisIfAvailable<DataLayout>();
184
215
}
@@ -257,6 +288,84 @@ struct NoTTI : ImmutablePass, TargetTransformInfo {
257
288
return TCC_Free;
258
289
}
259
290
291
+ unsigned getCallCost (FunctionType *FTy, int NumArgs = -1 ) const {
292
+ assert (FTy && " FunctionType must be provided to this routine." );
293
+
294
+ // The target-independent implementation just measures the size of the
295
+ // function by approximating that each argument will take on average one
296
+ // instruction to prepare.
297
+
298
+ if (NumArgs < 0 )
299
+ // Set the argument number to the number of explicit arguments in the
300
+ // function.
301
+ NumArgs = FTy->getNumParams ();
302
+
303
+ return TCC_Basic * (NumArgs + 1 );
304
+ }
305
+
306
+ unsigned getCallCost (const Function *F, int NumArgs = -1 ) const {
307
+ assert (F && " A concrete function must be provided to this routine." );
308
+
309
+ if (NumArgs < 0 )
310
+ // Set the argument number to the number of explicit arguments in the
311
+ // function.
312
+ NumArgs = F->arg_size ();
313
+
314
+ if (Intrinsic::ID IID = (Intrinsic::ID)F->getIntrinsicID ()) {
315
+ FunctionType *FTy = F->getFunctionType ();
316
+ SmallVector<Type *, 8 > ParamTys (FTy->param_begin (), FTy->param_end ());
317
+ return TopTTI->getIntrinsicCost (IID, FTy->getReturnType (), ParamTys);
318
+ }
319
+
320
+ if (!TopTTI->isLoweredToCall (F))
321
+ return TCC_Basic; // Give a basic cost if it will be lowered directly.
322
+
323
+ return TopTTI->getCallCost (F->getFunctionType (), NumArgs);
324
+ }
325
+
326
+ unsigned getCallCost (const Function *F,
327
+ ArrayRef<const Value *> Arguments) const {
328
+ // Simply delegate to generic handling of the call.
329
+ // FIXME: We should use instsimplify or something else to catch calls which
330
+ // will constant fold with these arguments.
331
+ return TopTTI->getCallCost (F, Arguments.size ());
332
+ }
333
+
334
+ unsigned getIntrinsicCost (Intrinsic::ID IID, Type *RetTy,
335
+ ArrayRef<Type *> ParamTys) const {
336
+ switch (IID) {
337
+ default :
338
+ // Intrinsics rarely (if ever) have normal argument setup constraints.
339
+ // Model them as having a basic instruction cost.
340
+ // FIXME: This is wrong for libc intrinsics.
341
+ return TCC_Basic;
342
+
343
+ case Intrinsic::dbg_declare:
344
+ case Intrinsic::dbg_value:
345
+ case Intrinsic::invariant_start:
346
+ case Intrinsic::invariant_end:
347
+ case Intrinsic::lifetime_start:
348
+ case Intrinsic::lifetime_end:
349
+ case Intrinsic::objectsize:
350
+ case Intrinsic::ptr_annotation:
351
+ case Intrinsic::var_annotation:
352
+ // These intrinsics don't actually represent code after lowering.
353
+ return TCC_Free;
354
+ }
355
+ }
356
+
357
+ unsigned getIntrinsicCost (Intrinsic::ID IID, Type *RetTy,
358
+ ArrayRef<const Value *> Arguments) const {
359
+ // Delegate to the generic intrinsic handling code. This mostly provides an
360
+ // opportunity for targets to (for example) special case the cost of
361
+ // certain intrinsics based on constants used as arguments.
362
+ SmallVector<Type *, 8 > ParamTys;
363
+ ParamTys.reserve (Arguments.size ());
364
+ for (unsigned Idx = 0 , Size = Arguments.size (); Idx != Size ; ++Idx)
365
+ ParamTys.push_back (Arguments[Idx]->getType ());
366
+ return TopTTI->getIntrinsicCost (IID, RetTy, ParamTys);
367
+ }
368
+
260
369
unsigned getUserCost (const User *U) const {
261
370
if (isa<PHINode>(U))
262
371
return TCC_Free; // Model all PHI nodes as free.
@@ -266,25 +375,21 @@ struct NoTTI : ImmutablePass, TargetTransformInfo {
266
375
// folded into their uses via addressing modes.
267
376
return GEP->hasAllConstantIndices () ? TCC_Free : TCC_Basic;
268
377
269
- // If we have a call of an intrinsic we can provide more detailed analysis
270
- // by inspecting the particular intrinsic called.
271
- // FIXME: Hoist this out into a getIntrinsicCost routine.
272
- if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) {
273
- switch (II->getIntrinsicID ()) {
274
- default :
275
- return TCC_Basic;
276
- case Intrinsic::dbg_declare:
277
- case Intrinsic::dbg_value:
278
- case Intrinsic::invariant_start:
279
- case Intrinsic::invariant_end:
280
- case Intrinsic::lifetime_start:
281
- case Intrinsic::lifetime_end:
282
- case Intrinsic::objectsize:
283
- case Intrinsic::ptr_annotation:
284
- case Intrinsic::var_annotation:
285
- // These intrinsics don't count as size.
286
- return TCC_Free;
378
+ if (ImmutableCallSite CS = U) {
379
+ const Function *F = CS.getCalledFunction ();
380
+ if (!F) {
381
+ // Just use the called value type.
382
+ Type *FTy = CS.getCalledValue ()->getType ()->getPointerElementType ();
383
+ return TopTTI->getCallCost (cast<FunctionType>(FTy), CS.arg_size ());
287
384
}
385
+
386
+ SmallVector<const Value *, 8 > Arguments;
387
+ for (ImmutableCallSite::arg_iterator AI = CS.arg_begin (),
388
+ AE = CS.arg_end ();
389
+ AI != AE; ++AI)
390
+ Arguments.push_back (*AI);
391
+
392
+ return TopTTI->getCallCost (F, Arguments);
288
393
}
289
394
290
395
if (const CastInst *CI = dyn_cast<CastInst>(U)) {
@@ -301,6 +406,37 @@ struct NoTTI : ImmutablePass, TargetTransformInfo {
301
406
U->getOperand (0 )->getType () : 0 );
302
407
}
303
408
409
+ bool isLoweredToCall (const Function *F) const {
410
+ // FIXME: These should almost certainly not be handled here, and instead
411
+ // handled with the help of TLI or the target itself. This was largely
412
+ // ported from existing analysis heuristics here so that such refactorings
413
+ // can take place in the future.
414
+
415
+ if (F->isIntrinsic ())
416
+ return false ;
417
+
418
+ if (F->hasLocalLinkage () || !F->hasName ())
419
+ return true ;
420
+
421
+ StringRef Name = F->getName ();
422
+
423
+ // These will all likely lower to a single selection DAG node.
424
+ if (Name == " copysign" || Name == " copysignf" || Name == " copysignl" ||
425
+ Name == " fabs" || Name == " fabsf" || Name == " fabsl" || Name == " sin" ||
426
+ Name == " sinf" || Name == " sinl" || Name == " cos" || Name == " cosf" ||
427
+ Name == " cosl" || Name == " sqrt" || Name == " sqrtf" || Name == " sqrtl" )
428
+ return false ;
429
+
430
+ // These are all likely to be optimized into something smaller.
431
+ if (Name == " pow" || Name == " powf" || Name == " powl" || Name == " exp2" ||
432
+ Name == " exp2l" || Name == " exp2f" || Name == " floor" || Name ==
433
+ " floorf" || Name == " ceil" || Name == " round" || Name == " ffs" ||
434
+ Name == " ffsl" || Name == " abs" || Name == " labs" || Name == " llabs" )
435
+ return false ;
436
+
437
+ return true ;
438
+ }
439
+
304
440
bool isLegalAddImmediate (int64_t Imm) const {
305
441
return false ;
306
442
}
0 commit comments