annotate gen/passes/SimplifyDRuntimeCalls.cpp @ 1545:7fcb72d518f6

More factory methods moved to LLVMContext
author Benjamin Kramer <benny.kra@gmail.com>
date Wed, 15 Jul 2009 18:09:41 +0200
parents 61f12f4651b5
children ed0feda76820
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;
1545
7fcb72d518f6 More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1535
diff changeset
49 LLVMContext *Context;
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
50
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 /// 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
52 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
53
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 /// 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
55 /// 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
56 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
57 unsigned Align, IRBuilder<> &B);
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
58 public:
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
59 LibCallOptimization() { }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
60 virtual ~LibCallOptimization() {}
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
61
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
62 /// 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
63 /// 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
64 /// 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
65 /// 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
66 /// delete CI.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
67 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
68
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
69 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
70 AliasAnalysis& AA, IRBuilder<> &B) {
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
71 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
72 this->Changed = &Changed;
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
73 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
74 this->AA = &AA;
1545
7fcb72d518f6 More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1535
diff changeset
75 if (CI->getCalledFunction())
7fcb72d518f6 More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1535
diff changeset
76 Context = CI->getCalledFunction()->getContext();
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
77 return CallOptimizer(CI->getCalledFunction(), CI, B);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
78 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
79 };
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
80 } // End anonymous namespace.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
81
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
82 /// 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
83 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
84 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
85 }
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
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 /// 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
88 /// 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
89 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
90 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
91 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
92 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
93 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
94 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
95 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
96 return B.CreateCall4(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len,
1545
7fcb72d518f6 More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1535
diff changeset
97 Context->getConstantInt(Type::Int32Ty, Align));
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
98 }
1275
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 // Miscellaneous LibCall Optimizations
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
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
104 namespace {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
105 //===---------------------------------------===//
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
106 // '_d_arraysetlengthT'/'_d_arraysetlengthiT' Optimizations
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
107
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
108 /// 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
109 struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
110 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
111 // 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
112 const FunctionType *FT = Callee->getFunctionType();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
113 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
114 !isa<IntegerType>(FT->getParamType(1)) ||
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
115 FT->getParamType(1) != FT->getParamType(2) ||
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
116 FT->getParamType(3) != FT->getReturnType())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
117 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
118
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
119 // 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
120 // Just delete if that's the case.
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
121 if (CI->use_empty())
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
122 return CI;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
123
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
124 Value* NewLen = CI->getOperand(2);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
125 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
126 Value* Data = CI->getOperand(4);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
127
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
128 // 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
129 //
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
130 // 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
131 // 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
132 // (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
133 // 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
134
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
135 // 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
136 if (NewCst->isNullValue())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
137 return Data;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
138
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
139 // 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
140 Value* OldLen = CI->getOperand(3);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
141 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
142 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
143 if (NewInt->getValue().ule(OldInt->getValue()))
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
144 return Data;
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 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
147 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
148 };
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
149
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
150 /// 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
151 struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
152 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
153 // 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
154 const FunctionType *FT = Callee->getFunctionType();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
155 const Type* RetTy = FT->getReturnType();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
156 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
157 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
158 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
159
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
160 Value* OldLen = CI->getOperand(1);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
161 Value* OldSize = CI->getOperand(2);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
162 Value* NewSize = CI->getOperand(3);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
163
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
164 // 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
165 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
166 if (LenCst->isNullValue())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
167 return OldLen;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
168
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
169 // 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
170 if (OldSize == NewSize)
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
171 return OldLen;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
172
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
173 // 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
174 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
175 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
176 // 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
177 if (NewInt->isNullValue())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
178 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
179
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
180 APInt Quot, Rem;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
181 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
182 if (Rem == 0)
1545
7fcb72d518f6 More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1535
diff changeset
183 return B.CreateMul(OldLen, Context->getConstantInt(Quot));
1275
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 return 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
186 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
187 };
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
188
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
189 /// 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
190 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
191 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
192 // 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
193 // 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
194 // 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
195 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
196 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
197
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
198 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
199 if (!Cmp->isEquality())
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
200 continue;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
201 Constant* C = 0;
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
202 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
203 || (C = dyn_cast<Constant>(Cmp->getOperand(1)))) {
1545
7fcb72d518f6 More factory methods moved to LLVMContext
Benjamin Kramer <benny.kra@gmail.com>
parents: 1535
diff changeset
204 Value* Result = Context->getConstantInt(Type::Int1Ty, !Cmp->isTrueWhenEqual());
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
205 Cmp->replaceAllUsesWith(Result);
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
206 // 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
207 // 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
208 // 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
209 // (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
210 // 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
211 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
212 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
213 *Changed = true;
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 }
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
216 }
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
217
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
218 // 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
219 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
220 return CI;
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
221 return 0;
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
222 }
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
223 };
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
224
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
225 /// 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
226 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
227 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
228 // 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
229 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
230 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
231 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
232 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
233 !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
234 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
235 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
236 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
237
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 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
239
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 // 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
241 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
242 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
243
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 // 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
245 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
246 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
247 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
248 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
249
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 // 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
251 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
252 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
253
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 // 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
255 // 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
256 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
257 }
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
258 };
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
259
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
260 // TODO: More optimizations! :)
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 } // end anonymous namespace.
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 // SimplifyDRuntimeCalls Pass Implementation
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
266 //===----------------------------------------------------------------------===//
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 namespace {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
269 /// 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
270 ///
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
271 class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
272 StringMap<LibCallOptimization*> Optimizations;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
273
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
274 // Array operations
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
275 ArraySetLengthOpt ArraySetLength;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
276 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
277 ArraySliceCopyOpt ArraySliceCopy;
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
278
1286
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
279 // GC allocations
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
280 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
281
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
282 public:
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
283 static char ID; // Pass identification
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
284 SimplifyDRuntimeCalls() : FunctionPass(&ID) {}
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
285
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
286 void InitOptimizations();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
287 bool runOnFunction(Function &F);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
288
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
289 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
290
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
291 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
292 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
293 AU.addRequired<AliasAnalysis>();
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
294 }
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 char SimplifyDRuntimeCalls::ID = 0;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
297 } // end anonymous namespace.
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 static RegisterPass<SimplifyDRuntimeCalls>
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
300 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
301
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
302 // Public interface to the pass.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
303 FunctionPass *createSimplifyDRuntimeCalls() {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
304 return new SimplifyDRuntimeCalls();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
305 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
306
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
307 /// 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
308 /// we know.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
309 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
310 // Some array-related optimizations
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
311 Optimizations["_d_arraysetlengthT"] = &ArraySetLength;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
312 Optimizations["_d_arraysetlengthiT"] = &ArraySetLength;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
313 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
314 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
315
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
316 /* 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
317 * 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
318 * 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
319 * 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
320 * '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
321 * be deleted.
23b23b74e326 Remove calls to some runtime functions if their results are unused
Frits van Bommel <fvbommel wxs.nl>
parents: 1275
diff changeset
322 * (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
323 * 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
324 */
1507
f86fd3b77285 Eliminate comparisons between GC allocations and constants. This removes some
Frits van Bommel <fvbommel wxs.nl>
parents: 1329
diff changeset
325 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
326 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
327 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
328 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
329 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
330 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
331 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
332 Optimizations["_d_allocclass"] = &Allocation;
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
333 }
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
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
336 /// runOnFunction - Top level algorithm.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
337 ///
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
338 bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
339 if (Optimizations.empty())
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
340 InitOptimizations();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
341
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
342 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
343 AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
344
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
345 // 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
346 // 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
347 // 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
348 // 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
349 // before the second one.
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
350 bool EverChanged = false;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
351 bool Changed;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
352 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
353 Changed = runOnce(F, TD, AA);
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
354 EverChanged |= Changed;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
355 } while (Changed);
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
356
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
357 return EverChanged;
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
358 }
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
359
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
360 bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA) {
1535
61f12f4651b5 Don't use llvm::getGlobalContext() anymore
Benjamin Kramer <benny.kra@gmail.com>
parents: 1529
diff changeset
361 IRBuilder<> Builder(*Context);
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
362
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
363 bool Changed = false;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
364 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
365 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
366 // Ignore non-calls.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
367 CallInst *CI = dyn_cast<CallInst>(I++);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
368 if (!CI) continue;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
369
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
370 // 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
371 Function *Callee = CI->getCalledFunction();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
372 if (Callee == 0 || !Callee->isDeclaration() ||
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
373 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
374 continue;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
375
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
376 // Ignore unknown calls.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
377 const char *CalleeName = Callee->getNameStart();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
378 StringMap<LibCallOptimization*>::iterator OMI =
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
379 Optimizations.find(CalleeName, CalleeName+Callee->getNameLen());
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
380 if (OMI == Optimizations.end()) continue;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
381
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
382 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
383
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
384 // 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
385 Builder.SetInsertPoint(BB, I);
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
386
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
387 // 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
388 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
389 if (Result == 0) continue;
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 DEBUG(DOUT << "SimplifyDRuntimeCalls simplified: " << *CI;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
392 DOUT << " into: " << *Result << "\n");
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
393
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
394 // Something changed!
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
395 Changed = true;
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
396
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
397 if (Result == CI) {
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
398 assert(CI->use_empty());
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
399 ++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
400 AA.deleteValue(CI);
1319
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
401 } else {
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
402 ++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
403 AA.replaceWithNewValue(CI, Result);
1319
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 (!CI->use_empty())
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
406 CI->replaceAllUsesWith(Result);
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
407
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
408 if (!Result->hasName())
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
409 Result->takeName(CI);
c32e27f9a61d Some tweaks to -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents: 1286
diff changeset
410 }
1275
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
411
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
412 // 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
413 // added) next.
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
414 I = CI; ++I;
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 CI->eraseFromParent();
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
417 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
418 }
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
419 return Changed;
bedf0bfb8fdb Implement first D-specific optimization pass: -simplify-drtcalls.
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
420 }