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
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// This include file determines how VARSET_TP is implemented.
//
#ifndef _VARSET_INCLUDED_
#define _VARSET_INCLUDED_ 1
// A VARSET_TP is a set of (small) integers representing local variables.
// We implement varsets using the BitSet abstraction, which supports
// several different implementations.
//
// The set of tracked variables may change during a compilation, and variables may be
// re-sorted, so the tracked variable index of a variable is decidedly *not* stable. The
// bitset abstraction supports labeling of bitsets with "epochs", and supports a
// debugging mode in which live bitsets must have the current epoch. To use this feature,
// divide a compilation up into epochs, during which tracked variable indices are
// stable.
// Some implementations of BitSet may use a level of indirection. Therefore, we
// must be careful about about assignment and initialization. We often want to
// reason about VARSET_TP as immutable values, and just copying the contents would
// introduce sharing in the indirect case, which is usually not what's desired. On
// the other hand, there are many cases in which the RHS value has just been
// created functionally, and the intialization/assignment is obviously its last
// use. In these cases, allocating a new indirect representation for the lhs (if
// it does not already have one) would be unnecessary and wasteful. Thus, for both
// initialization and assignment, we have normal versions, which do make copies to
// prevent sharing and definitely preserve value semantics, and "NOCOPY" versions,
// which do not. Obviously, the latter should be used with care.
#include "bitset.h"
#include "compilerbitsettraits.h"
const unsigned UInt64Bits = sizeof(UINT64) * 8;
// This #define chooses the BitSet representation used for VARSET.
// The choices are defined in "bitset.h"; they currently include
// BSUInt64, BSShortLong, and BSUInt64Class.
#define VARSET_REP BSShortLong
#if VARSET_REP == BSUInt64
#include "bitsetasuint64.h"
typedef BitSetOps</*BitSetType*/ UINT64,
/*Brand*/ VARSET_REP,
/*Env*/ Compiler*,
/*BitSetTraits*/ TrackedVarBitSetTraits>
VarSetOpsRaw;
typedef UINT64 VARSET_TP;
const unsigned lclMAX_TRACKED = UInt64Bits;
#define VARSET_REP_IS_CLASS 0
#elif VARSET_REP == BSShortLong
#include "bitsetasshortlong.h"
typedef BitSetOps</*BitSetType*/ BitSetShortLongRep,
/*Brand*/ VARSET_REP,
/*Env*/ Compiler*,
/*BitSetTraits*/ TrackedVarBitSetTraits>
VarSetOpsRaw;
typedef BitSetShortLongRep VARSET_TP;
// Tested various sizes for max tracked locals. The largest value for which no throughput regression
// could be measured was 512. Going to 1024 showed the first throughput regressions.
// We anticipate the larger size will be needed to support better inlining.
const unsigned lclMAX_TRACKED = 512;
#define VARSET_REP_IS_CLASS 0
#elif VARSET_REP == BSUInt64Class
#include "bitsetasuint64inclass.h"
typedef BitSetOps</*BitSetType*/ BitSetUint64<Compiler*, TrackedVarBitSetTraits>,
/*Brand*/ VARSET_REP,
/*Env*/ Compiler*,
/*BitSetTraits*/ TrackedVarBitSetTraits>
VarSetOpsRaw;
typedef BitSetUint64<Compiler*, TrackedVarBitSetTraits> VARSET_TP;
const unsigned lclMAX_TRACKED = UInt64Bits;
#define VARSET_REP_IS_CLASS 1
#else
#error "Unrecognized BitSet implemention for VarSet."
#endif
// These types should be used as the types for VARSET_TP arguments and return values, respectively.
// Arg type represent the read only argument type, that can't be modified.
typedef VarSetOpsRaw::ValArgType VARSET_VALARG_TP;
typedef VarSetOpsRaw::RetValType VARSET_VALRET_TP;
#define VARSET_COUNTOPS 0
#if VARSET_COUNTOPS
typedef BitSetOpsWithCounter<VARSET_TP,
VARSET_REP,
Compiler*,
TrackedVarBitSetTraits,
VARSET_VALARG_TP,
VARSET_VALRET_TP,
VarSetOpsRaw::Iter>
VarSetOps;
#else
typedef VarSetOpsRaw VarSetOps;
#endif
#define ALLVARSET_REP BSUInt64
#if ALLVARSET_REP == BSUInt64
#include "bitsetasuint64.h"
typedef BitSetOps</*BitSetType*/ UINT64,
/*Brand*/ ALLVARSET_REP,
/*Env*/ Compiler*,
/*BitSetTraits*/ AllVarBitSetTraits>
AllVarSetOps;
typedef UINT64 ALLVARSET_TP;
const unsigned lclMAX_ALLSET_TRACKED = UInt64Bits;
#define ALLVARSET_REP_IS_CLASS 0
#elif ALLVARSET_REP == BSShortLong
#include "bitsetasshortlong.h"
typedef BitSetOps</*BitSetType*/ BitSetShortLongRep,
/*Brand*/ ALLVARSET_REP,
/*Env*/ Compiler*,
/*BitSetTraits*/ AllVarBitSetTraits>
AllVarSetOps;
typedef BitSetShortLongRep ALLVARSET_TP;
const unsigned lclMAX_ALLSET_TRACKED = lclMAX_TRACKED;
#define ALLVARSET_REP_IS_CLASS 0
#elif ALLVARSET_REP == BSUInt64Class
#include "bitsetasuint64inclass.h"
typedef BitSetOps</*BitSetType*/ BitSetUint64<Compiler*, AllVarBitSetTraits>,
/*Brand*/ ALLVARSET_REP,
/*Env*/ Compiler*,
/*BitSetTraits*/ AllVarBitSetTraits>
AllVarSetOps;
typedef BitSetUint64<Compiler*, AllVarBitSetTraits> ALLVARSET_TP;
const unsigned lclMAX_ALLSET_TRACKED = UInt64Bits;
#define ALLVARSET_REP_IS_CLASS 1
#else
#error "Unrecognized BitSet implemention for AllVarSet."
#endif
// These types should be used as the types for ALLVARSET_TP arguments and return values, respectively.
typedef AllVarSetOps::ValArgType ALLVARSET_VALARG_TP;
typedef AllVarSetOps::RetValType ALLVARSET_VALRET_TP;
#endif // _VARSET_INCLUDED_
|