annotate gen/passes/SimplifyDRuntimeCalls.cpp @ 1507:f86fd3b77285

Eliminate comparisons between GC allocations and constants. This removes some `assert(this !is null)`s when member functions get inlined. Also tweak pass order a bit.
author Frits van Bommel <fvbommel wxs.nl>
date Sat, 20 Jun 2009 14:28:59 +0200
parents e5b57fd8307c
children ad7f2f1862d6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
1 //===- SimplifyDRuntimeCalls - Optimize calls to the D runtime library ----===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
2 //
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
3 // The LLVM D Compiler
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
4 //
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
5 // This file is distributed under the University of Illinois Open Source
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
6 // License. See LICENSE.TXT for details.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
7 //
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
9 //
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
10 // This file implements a simple pass that applies a variety of small
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
11 // optimizations for calls to specific functions in the D runtime.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
12 //
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
13 // The machinery was copied from the standard -simplify-libcalls LLVM pass.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
14 //
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
15 //===----------------------------------------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
16
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
17 #define DEBUG_TYPE "simplify-drtcalls"
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
18
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
19 #include "Passes.h"
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
20
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
21 #include "llvm/Pass.h"
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
22 #include "llvm/Intrinsics.h"
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
23 #include "llvm/Support/IRBuilder.h"
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
24 #include "llvm/Analysis/AliasAnalysis.h"
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
25 #include "llvm/Analysis/ValueTracking.h"
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
26 #include "llvm/Target/TargetData.h"
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
27 #include "llvm/ADT/StringMap.h"
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
28 #include "llvm/ADT/Statistic.h"
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
29 #include "llvm/Support/Compiler.h"
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
30 #include "llvm/Support/Debug.h"
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
31 using namespace llvm;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
32
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
33 STATISTIC(NumSimplified, "Number of runtime calls simplified");
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
34 STATISTIC(NumDeleted, "Number of runtime calls deleted");
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
35
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
36 //===----------------------------------------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
37 // Optimizer Base Class
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
38 //===----------------------------------------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
39
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
40 /// This class is the abstract base class for the set of optimizations that
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
41 /// corresponds to one library call.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
42 namespace {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
43 class VISIBILITY_HIDDEN LibCallOptimization {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
44 protected:
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
45 Function *Caller;
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
46 bool* Changed;
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
47 const TargetData *TD;
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
48 AliasAnalysis *AA;
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
49
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
50 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
51 Value *CastToCStr(Value *V, IRBuilder<> &B);
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
52
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
53 /// EmitMemCpy - Emit a call to the memcpy function to the builder. This
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
54 /// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
55 Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len,
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
56 unsigned Align, IRBuilder<> &B);
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
57 public:
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
58 LibCallOptimization() { }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
59 virtual ~LibCallOptimization() {}
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
60
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
61 /// CallOptimizer - This pure virtual method is implemented by base classes to
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
62 /// do various optimizations. If this returns null then no transformation was
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
63 /// performed. If it returns CI, then it transformed the call and CI is to be
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
64 /// deleted. If it returns something else, replace CI with the new value and
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
65 /// delete CI.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
66 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
67
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
68 Value *OptimizeCall(CallInst *CI, bool& Changed, const TargetData &TD,
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
69 AliasAnalysis& AA, IRBuilder<> &B) {
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
70 Caller = CI->getParent()->getParent();
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
71 this->Changed = &Changed;
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
72 this->TD = &TD;
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
73 this->AA = &AA;
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
74 return CallOptimizer(CI->getCalledFunction(), CI, B);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
75 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
76 };
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
77 } // End anonymous namespace.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
78
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
79 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
80 Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) {
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
81 return B.CreateBitCast(V, PointerType::getUnqual(Type::Int8Ty), "cstr");
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
82 }
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
83
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
84 /// EmitMemCpy - Emit a call to the memcpy function to the builder. This always
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
85 /// expects that the size has type 'intptr_t' and Dst/Src are pointers.
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
86 Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
87 unsigned Align, IRBuilder<> &B) {
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
88 Module *M = Caller->getParent();
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
89 Intrinsic::ID IID = Intrinsic::memcpy;
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
90 const Type *Tys[1];
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
91 Tys[0] = Len->getType();
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
92 Value *MemCpy = Intrinsic::getDeclaration(M, IID, Tys, 1);
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
93 return B.CreateCall4(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len,
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
94 ConstantInt::get(Type::Int32Ty, Align));
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
95 }
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
96
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
97 //===----------------------------------------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
98 // Miscellaneous LibCall Optimizations
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
99 //===----------------------------------------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
100
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
101 namespace {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
102 //===---------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
103 // '_d_arraysetlengthT'/'_d_arraysetlengthiT' Optimizations
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
104
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
105 /// ArraySetLengthOpt - remove libcall for arr.length = N if N <= arr.length
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
106 struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
107 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
108 // Verify we have a reasonable prototype for _d_arraysetlength[i]T
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
109 const FunctionType *FT = Callee->getFunctionType();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
110 if (Callee->arg_size() != 4 || !isa<PointerType>(FT->getReturnType()) ||
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
111 !isa<IntegerType>(FT->getParamType(1)) ||
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
112 FT->getParamType(1) != FT->getParamType(2) ||
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
113 FT->getParamType(3) != FT->getReturnType())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
114 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
115
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
116 // Whether or not this allocates is irrelevant if the result isn't used.
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
117 // Just delete if that's the case.
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
118 if (CI->use_empty())
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
119 return CI;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
120
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
121 Value* NewLen = CI->getOperand(2);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
122 if (Constant* NewCst = dyn_cast<Constant>(NewLen)) {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
123 Value* Data = CI->getOperand(4);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
124
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
125 // For now, we just catch the simplest of cases.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
126 //
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
127 // TODO: Implement a more general way to compare old and new
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
128 // lengths, to catch cases like "arr.length = arr.length - 1;"
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
129 // (But beware of unsigned overflow! For example, we can't
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
130 // safely transform that example if arr.length may be 0)
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
131
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
132 // Setting length to 0 never reallocates, so replace by data argument
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
133 if (NewCst->isNullValue())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
134 return Data;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
135
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
136 // If both lengths are constant integers, see if NewLen <= OldLen
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
137 Value* OldLen = CI->getOperand(3);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
138 if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldLen))
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
139 if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewCst))
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
140 if (NewInt->getValue().ule(OldInt->getValue()))
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
141 return Data;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
142 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
143 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
144 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
145 };
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
146
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
147 /// ArrayCastLenOpt - remove libcall for cast(T[]) arr if it's safe to do so.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
148 struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
149 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
150 // Verify we have a reasonable prototype for _d_array_cast_len
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
151 const FunctionType *FT = Callee->getFunctionType();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
152 const Type* RetTy = FT->getReturnType();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
153 if (Callee->arg_size() != 3 || !isa<IntegerType>(RetTy) ||
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
154 FT->getParamType(1) != RetTy || FT->getParamType(2) != RetTy)
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
155 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
156
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
157 Value* OldLen = CI->getOperand(1);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
158 Value* OldSize = CI->getOperand(2);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
159 Value* NewSize = CI->getOperand(3);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
160
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
161 // If the old length was zero, always return zero.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
162 if (Constant* LenCst = dyn_cast<Constant>(OldLen))
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
163 if (LenCst->isNullValue())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
164 return OldLen;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
165
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
166 // Equal sizes are much faster to check for, so do so now.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
167 if (OldSize == NewSize)
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
168 return OldLen;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
169
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
170 // If both sizes are constant integers, see if OldSize is a multiple of NewSize
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
171 if (ConstantInt* OldInt = dyn_cast<ConstantInt>(OldSize))
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
172 if (ConstantInt* NewInt = dyn_cast<ConstantInt>(NewSize)) {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
173 // Don't crash on NewSize == 0, even though it shouldn't happen.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
174 if (NewInt->isNullValue())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
175 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
176
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
177 APInt Quot, Rem;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
178 APInt::udivrem(OldInt->getValue(), NewInt->getValue(), Quot, Rem);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
179 if (Rem == 0)
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
180 return B.CreateMul(OldLen, ConstantInt::get(Quot));
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
181 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
182 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
183 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
184 };
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
185
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
186 /// AllocationOpt - Common optimizations for various GC allocations.
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
187 struct VISIBILITY_HIDDEN AllocationOpt : public LibCallOptimization {
1286
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
188 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
189 // Allocations are never equal to constants, so remove any equality
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
190 // comparisons to constants. (Most importantly comparisons to null at
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
191 // the start of inlined member functions)
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
192 for (CallInst::use_iterator I = CI->use_begin(), E = CI->use_end() ; I != E;) {
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
193 Instruction* User = cast<Instruction>(*I++);
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
194
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
195 if (ICmpInst* Cmp = dyn_cast<ICmpInst>(User)) {
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
196 if (!Cmp->isEquality())
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
197 continue;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
198 Constant* C = 0;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
199 if ((C = dyn_cast<Constant>(Cmp->getOperand(0)))
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
200 || (C = dyn_cast<Constant>(Cmp->getOperand(1)))) {
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
201 Value* Result = ConstantInt::get(Type::Int1Ty, !Cmp->isTrueWhenEqual());
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
202 Cmp->replaceAllUsesWith(Result);
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
203 // Don't delete the comparison because there may be an
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
204 // iterator to it. Instead, set the operands to constants
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
205 // and let dead code elimination clean it up later.
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
206 // (It doesn't matter that this changes the value of the
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
207 // icmp because it's not used anymore anyway)
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
208 Cmp->setOperand(0, C);
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
209 Cmp->setOperand(1, C);
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
210 *Changed = true;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
211 }
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
212 }
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
213 }
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
214
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
215 // If it's not used (anymore), pre-emptively GC it.
1286
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
216 if (CI->use_empty())
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
217 return CI;
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
218 return 0;
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
219 }
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
220 };
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
221
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
222 /// ArraySliceCopyOpt - Turn slice copies into llvm.memcpy when safe
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
223 struct VISIBILITY_HIDDEN ArraySliceCopyOpt : public LibCallOptimization {
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
224 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
225 // Verify we have a reasonable prototype for _d_array_slice_copy
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
226 const FunctionType *FT = Callee->getFunctionType();
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
227 const Type* VoidPtrTy = PointerType::getUnqual(Type::Int8Ty);
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
228 if (Callee->arg_size() != 4 || FT->getReturnType() != Type::VoidTy ||
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
229 FT->getParamType(0) != VoidPtrTy ||
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
230 !isa<IntegerType>(FT->getParamType(1)) ||
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
231 FT->getParamType(2) != VoidPtrTy ||
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
232 FT->getParamType(3) != FT->getParamType(1))
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
233 return 0;
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
234
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
235 Value* Size = CI->getOperand(2);
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
236
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
237 // Check the lengths match
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
238 if (CI->getOperand(4) != Size)
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
239 return 0;
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
240
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
241 // Assume unknown size unless we have constant size (that fits in an uint)
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
242 unsigned Sz = ~0U;
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
243 if (ConstantInt* Int = dyn_cast<ConstantInt>(Size))
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
244 if (Int->getValue().isIntN(32))
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
245 Sz = Int->getValue().getZExtValue();
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
246
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
247 // Check if the pointers may alias
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
248 if (AA->alias(CI->getOperand(1), Sz, CI->getOperand(3), Sz))
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
249 return 0;
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
250
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
251 // Equal length and the pointers definitely don't alias, so it's safe to
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
252 // replace the call with memcpy
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
253 return EmitMemCpy(CI->getOperand(1), CI->getOperand(3), Size, 0, B);
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
254 }
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
255 };
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
256
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
257 // TODO: More optimizations! :)
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
258
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
259 } // end anonymous namespace.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
260
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
261 //===----------------------------------------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
262 // SimplifyDRuntimeCalls Pass Implementation
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
263 //===----------------------------------------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
264
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
265 namespace {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
266 /// This pass optimizes library functions from the D runtime as used by LDC.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
267 ///
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
268 class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
269 StringMap<LibCallOptimization*> Optimizations;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
270
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
271 // Array operations
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
272 ArraySetLengthOpt ArraySetLength;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
273 ArrayCastLenOpt ArrayCastLen;
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
274 ArraySliceCopyOpt ArraySliceCopy;
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
275
1286
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
276 // GC allocations
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
277 AllocationOpt Allocation;
1286
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
278
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
279 public:
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
280 static char ID; // Pass identification
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
281 SimplifyDRuntimeCalls() : FunctionPass(&ID) {}
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
282
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
283 void InitOptimizations();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
284 bool runOnFunction(Function &F);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
285
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
286 bool runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA);
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
287
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
288 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
289 AU.addRequired<TargetData>();
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
290 AU.addRequired<AliasAnalysis>();
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
291 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
292 };
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
293 char SimplifyDRuntimeCalls::ID = 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
294 } // end anonymous namespace.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
295
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
296 static RegisterPass<SimplifyDRuntimeCalls>
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
297 X("simplify-drtcalls", "Simplify calls to D runtime");
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
298
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
299 // Public interface to the pass.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
300 FunctionPass *createSimplifyDRuntimeCalls() {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
301 return new SimplifyDRuntimeCalls();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
302 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
303
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
304 /// Optimizations - Populate the Optimizations map with all the optimizations
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
305 /// we know.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
306 void SimplifyDRuntimeCalls::InitOptimizations() {
1286
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
307 // Some array-related optimizations
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
308 Optimizations["_d_arraysetlengthT"] = &ArraySetLength;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
309 Optimizations["_d_arraysetlengthiT"] = &ArraySetLength;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
310 Optimizations["_d_array_cast_len"] = &ArrayCastLen;
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
311 Optimizations["_d_array_slice_copy"] = &ArraySliceCopy;
1286
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
312
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
313 /* Delete calls to runtime functions which aren't needed if their result is
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
314 * unused. That comes down to functions that don't do anything but
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
315 * GC-allocate and initialize some memory.
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
316 * We don't need to do this for functions which are marked 'readnone' or
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
317 * 'readonly', since LLVM doesn't need our help figuring out when those can
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
318 * be deleted.
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
319 * (We can't mark allocating calls as readonly/readnone because they don't
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
320 * return the same pointer every time when called with the same arguments)
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
321 */
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
322 Optimizations["_d_allocmemoryT"] = &Allocation;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
323 Optimizations["_d_newarrayT"] = &Allocation;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
324 Optimizations["_d_newarrayiT"] = &Allocation;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
325 Optimizations["_d_newarrayvT"] = &Allocation;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
326 Optimizations["_d_newarraymT"] = &Allocation;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
327 Optimizations["_d_newarraymiT"] = &Allocation;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
328 Optimizations["_d_newarraymvT"] = &Allocation;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
329 Optimizations["_d_allocclass"] = &Allocation;
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
330 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
331
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
332
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
333 /// runOnFunction - Top level algorithm.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
334 ///
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
335 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
336 if (Optimizations.empty())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
337 InitOptimizations();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
338
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
339 const TargetData &TD = getAnalysis<TargetData>();
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
340 AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
341
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
342 // Iterate to catch opportunities opened up by other optimizations,
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
343 // such as calls that are only used as arguments to unused calls:
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
344 // When the second call gets deleted the first call will become unused, but
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
345 // without iteration we wouldn't notice if we inspected the first call
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
346 // before the second one.
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
347 bool EverChanged = false;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
348 bool Changed;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
349 do {
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
350 Changed = runOnce(F, TD, AA);
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
351 EverChanged |= Changed;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
352 } while (Changed);
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
353
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
354 return EverChanged;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
355 }
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
356
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
357 bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA) {
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
358 IRBuilder<> Builder;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
359
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
360 bool Changed = false;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
361 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
362 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
363 // Ignore non-calls.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
364 CallInst *CI = dyn_cast<CallInst>(I++);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
365 if (!CI) continue;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
366
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
367 // Ignore indirect calls and calls to non-external functions.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
368 Function *Callee = CI->getCalledFunction();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
369 if (Callee == 0 || !Callee->isDeclaration() ||
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
370 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
371 continue;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
372
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
373 // Ignore unknown calls.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
374 const char *CalleeName = Callee->getNameStart();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
375 StringMap<LibCallOptimization*>::iterator OMI =
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
376 Optimizations.find(CalleeName, CalleeName+Callee->getNameLen());
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
377 if (OMI == Optimizations.end()) continue;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
378
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
379 DEBUG(DOUT << "SimplifyDRuntimeCalls inspecting: " << *CI);
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
380
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
381 // Set the builder to the instruction after the call.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
382 Builder.SetInsertPoint(BB, I);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
383
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
384 // Try to optimize this call.
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
385 Value *Result = OMI->second->OptimizeCall(CI, Changed, TD, AA, Builder);
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
386 if (Result == 0) continue;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
387
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
388 DEBUG(DOUT << "SimplifyDRuntimeCalls simplified: " << *CI;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
389 DOUT << " into: " << *Result << "\n");
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
390
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
391 // Something changed!
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
392 Changed = true;
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
393
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
394 if (Result == CI) {
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
395 assert(CI->use_empty());
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
396 ++NumDeleted;
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
397 AA.deleteValue(CI);
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
398 } else {
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
399 ++NumSimplified;
1329
e5b57fd8307c Turn new _d_array_slice_copy runtime call into memcpy when the slice lengths are
Frits van Bommel <fvbommel wxs.nl>
parents: 1319
diff changeset
400 AA.replaceWithNewValue(CI, Result);
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
401
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
402 if (!CI->use_empty())
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
403 CI->replaceAllUsesWith(Result);
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
404
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
405 if (!Result->hasName())
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
406 Result->takeName(CI);
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
407 }
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
408
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
409 // Inspect the instruction after the call (which was potentially just
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
410 // added) next.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
411 I = CI; ++I;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
412
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
413 CI->eraseFromParent();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
414 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
415 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
416 return Changed;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
417 }