-
Notifications
You must be signed in to change notification settings - Fork 115
/
Optimizer.cs
220 lines (196 loc) · 7.95 KB
/
Optimizer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// ---------------------------------------------------------------------------------------
// ILGPU
// Copyright (c) 2016-2020 Marcel Koester
// www.ilgpu.net
//
// File: Optimizer.cs
//
// This file is part of ILGPU and is distributed under the University of Illinois Open
// Source License. See LICENSE.txt for details
// ---------------------------------------------------------------------------------------
using ILGPU.Backends.PointerViews;
using System;
namespace ILGPU.IR.Transformations
{
/// <summary>
/// Represent an optimization level.
/// </summary>
public enum OptimizationLevel
{
/// <summary>
/// Defaults to O0.
/// </summary>
Debug = O0,
/// <summary>
/// Defaults to O1.
/// </summary>
Release = O1,
/// <summary>
/// Lightweight (required) transformations only.
/// </summary>
O0 = 0,
/// <summary>
/// Default release mode transformations.
/// </summary>
O1 = 1,
/// <summary>
/// Expensive transformations.
/// </summary>
O2 = 2,
}
/// <summary>
/// Realizes utility helpers to perform and initialize transformations
/// based on an <see cref="OptimizationLevel"/>.
/// </summary>
public static class Optimizer
{
/// <summary>
/// Returns the number of known optimization levels.
/// </summary>
public const int NumOptimizationLevels = 3;
/// <summary>
/// Internal mapping from optimization levels to handlers.
/// </summary>
private static readonly Action<Transformer.Builder, ContextFlags>[]
OptimizationHandlers =
{
AddO0Optimizations,
AddO1Optimizations,
AddO2Optimizations,
};
/// <summary>
/// Populates the given transformation manager with the required
/// optimization transformations.
/// </summary>
/// <param name="builder">The transformation manager to populate.</param>
/// <param name="contextFlags">The context flags.</param>
/// <param name="level">The desired optimization level.</param>
/// <returns>The maximum number of iterations.</returns>
public static void AddOptimizations(
this Transformer.Builder builder,
ContextFlags contextFlags,
OptimizationLevel level)
{
if (level < OptimizationLevel.O0 || level > OptimizationLevel.O2)
throw new ArgumentOutOfRangeException(nameof(level));
OptimizationHandlers[(int)level](builder, contextFlags);
}
/// <summary>
/// Adds basic optimization transformations.
/// </summary>
/// <param name="builder">The transformation manager to populate.</param>
/// <param name="contextFlags">The context flags.</param>
public static void AddBasicOptimizations(
this Transformer.Builder builder,
ContextFlags contextFlags)
{
if (!contextFlags.HasFlags(ContextFlags.NoInlining))
builder.Add(new Inliner());
builder.Add(new SimplifyControlFlow());
}
/// <summary>
/// Adds general backend optimizations.
/// </summary>
/// <param name="builder">The transformation manager to populate.</param>
/// <param name="acceleratorSpecializer">
/// An instance of an <see cref="AcceleratorSpecializer"/> class.
/// </param>
/// <param name="level">The desired optimization level.</param>
public static void AddBackendOptimizations(
this Transformer.Builder builder,
AcceleratorSpecializer acceleratorSpecializer,
OptimizationLevel level)
{
// Specialize accelerator properties and views
builder.Add(new LowerArrays());
builder.Add(new LowerPointerViews());
builder.Add(acceleratorSpecializer);
// Specialize all parameter address spaces
if (level > OptimizationLevel.O1)
builder.Add(new AddressSpaceSpecializer(MemoryAddressSpace.Global));
// Lower structures
if (level > OptimizationLevel.O1)
builder.Add(new LowerStructures());
// Apply final DCE phase in release mode
if (level > OptimizationLevel.O0)
builder.Add(new DeadCodeElimination());
// Infer all specialized address spaces
if (level > OptimizationLevel.O1)
builder.Add(new InferAddressSpaces());
// Append further backend specific transformations in release mode
builder.Add(new Inliner());
if (level > OptimizationLevel.O0)
builder.Add(new SimplifyControlFlow());
}
/// <summary>
/// Populates the given transformation manager with O0 optimizations.
/// </summary>
/// <param name="builder">The transformation manager to populate.</param>
/// <param name="contextFlags">The context flags.</param>
public static void AddO0Optimizations(
this Transformer.Builder builder,
ContextFlags contextFlags)
{
builder.AddBasicOptimizations(contextFlags);
builder.Add(new SSAConstruction());
builder.Add(new DeadCodeElimination());
builder.Add(new InferAddressSpaces());
}
/// <summary>
/// Populates the given transformation manager with O1 optimizations.
/// </summary>
/// <param name="builder">The transformation manager to populate.</param>
/// <param name="contextFlags">The context flags.</param>
public static void AddO1Optimizations(
this Transformer.Builder builder,
ContextFlags contextFlags)
{
var dce = new DeadCodeElimination();
builder.AddBasicOptimizations(contextFlags);
builder.Add(dce);
builder.Add(new SSAConstruction());
builder.Add(dce);
builder.Add(new InferAddressSpaces());
}
/// <summary>
/// Populates the given transformation manager with O2 optimizations.
/// </summary>
/// <param name="builder">The transformation manager to populate.</param>
/// <param name="contextFlags">The context flags.</param>
public static void AddO2Optimizations(
this Transformer.Builder builder,
ContextFlags contextFlags)
{
var dce = new DeadCodeElimination();
var scf = new SimplifyControlFlow();
builder.AddBasicOptimizations(contextFlags);
builder.Add(dce);
builder.Add(new SSAConstruction());
builder.Add(new LowerStructures());
builder.Add(dce);
builder.Add(new LoopUnrolling());
builder.Add(dce);
builder.Add(scf);
builder.Add(new IfConversion(IfConversionFlags.Default));
builder.Add(dce);
builder.Add(scf);
builder.Add(new InferAddressSpaces());
}
/// <summary>
/// Creates a transformer for the given optimization level.
/// </summary>
/// <param name="level">The level.</param>
/// <param name="configuration">The transformer configuration.</param>
/// <param name="contextFlags">The context flags.</param>
/// <returns>The created transformer.</returns>
public static Transformer CreateTransformer(
this OptimizationLevel level,
TransformerConfiguration configuration,
ContextFlags contextFlags)
{
var builder = Transformer.CreateBuilder(configuration);
builder.AddOptimizations(contextFlags, level);
return builder.ToTransformer();
}
}
}