@@ -2066,194 +2066,6 @@ OptimizeGlobalVars(Module &M,
2066
2066
return Changed;
2067
2067
}
2068
2068
2069
- // / Evaluate a piece of a constantexpr store into a global initializer. This
2070
- // / returns 'Init' modified to reflect 'Val' stored into it. At this point, the
2071
- // / GEP operands of Addr [0, OpNo) have been stepped into.
2072
- static Constant *EvaluateStoreInto (Constant *Init, Constant *Val,
2073
- ConstantExpr *Addr, unsigned OpNo) {
2074
- // Base case of the recursion.
2075
- if (OpNo == Addr->getNumOperands ()) {
2076
- assert (Val->getType () == Init->getType () && " Type mismatch!" );
2077
- return Val;
2078
- }
2079
-
2080
- SmallVector<Constant*, 32 > Elts;
2081
- if (StructType *STy = dyn_cast<StructType>(Init->getType ())) {
2082
- // Break up the constant into its elements.
2083
- for (unsigned i = 0 , e = STy->getNumElements (); i != e; ++i)
2084
- Elts.push_back (Init->getAggregateElement (i));
2085
-
2086
- // Replace the element that we are supposed to.
2087
- ConstantInt *CU = cast<ConstantInt>(Addr->getOperand (OpNo));
2088
- unsigned Idx = CU->getZExtValue ();
2089
- assert (Idx < STy->getNumElements () && " Struct index out of range!" );
2090
- Elts[Idx] = EvaluateStoreInto (Elts[Idx], Val, Addr, OpNo+1 );
2091
-
2092
- // Return the modified struct.
2093
- return ConstantStruct::get (STy, Elts);
2094
- }
2095
-
2096
- ConstantInt *CI = cast<ConstantInt>(Addr->getOperand (OpNo));
2097
- uint64_t NumElts;
2098
- if (ArrayType *ATy = dyn_cast<ArrayType>(Init->getType ()))
2099
- NumElts = ATy->getNumElements ();
2100
- else
2101
- NumElts = cast<FixedVectorType>(Init->getType ())->getNumElements ();
2102
-
2103
- // Break up the array into elements.
2104
- for (uint64_t i = 0 , e = NumElts; i != e; ++i)
2105
- Elts.push_back (Init->getAggregateElement (i));
2106
-
2107
- assert (CI->getZExtValue () < NumElts);
2108
- Elts[CI->getZExtValue ()] =
2109
- EvaluateStoreInto (Elts[CI->getZExtValue ()], Val, Addr, OpNo+1 );
2110
-
2111
- if (Init->getType ()->isArrayTy ())
2112
- return ConstantArray::get (cast<ArrayType>(Init->getType ()), Elts);
2113
- return ConstantVector::get (Elts);
2114
- }
2115
-
2116
- // / We have decided that Addr (which satisfies the predicate
2117
- // / isSimpleEnoughPointerToCommit) should get Val as its value. Make it happen.
2118
- static void CommitValueTo (Constant *Val, Constant *Addr) {
2119
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) {
2120
- assert (GV->hasInitializer ());
2121
- GV->setInitializer (Val);
2122
- return ;
2123
- }
2124
-
2125
- ConstantExpr *CE = cast<ConstantExpr>(Addr);
2126
- GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand (0 ));
2127
- GV->setInitializer (EvaluateStoreInto (GV->getInitializer (), Val, CE, 2 ));
2128
- }
2129
-
2130
- // / Given a map of address -> value, where addresses are expected to be some form
2131
- // / of either a global or a constant GEP, set the initializer for the address to
2132
- // / be the value. This performs mostly the same function as CommitValueTo()
2133
- // / and EvaluateStoreInto() but is optimized to be more efficient for the common
2134
- // / case where the set of addresses are GEPs sharing the same underlying global,
2135
- // / processing the GEPs in batches rather than individually.
2136
- // /
2137
- // / To give an example, consider the following C++ code adapted from the clang
2138
- // / regression tests:
2139
- // / struct S {
2140
- // / int n = 10;
2141
- // / int m = 2 * n;
2142
- // / S(int a) : n(a) {}
2143
- // / };
2144
- // /
2145
- // / template<typename T>
2146
- // / struct U {
2147
- // / T *r = &q;
2148
- // / T q = 42;
2149
- // / U *p = this;
2150
- // / };
2151
- // /
2152
- // / U<S> e;
2153
- // /
2154
- // / The global static constructor for 'e' will need to initialize 'r' and 'p' of
2155
- // / the outer struct, while also initializing the inner 'q' structs 'n' and 'm'
2156
- // / members. This batch algorithm will simply use general CommitValueTo() method
2157
- // / to handle the complex nested S struct initialization of 'q', before
2158
- // / processing the outermost members in a single batch. Using CommitValueTo() to
2159
- // / handle member in the outer struct is inefficient when the struct/array is
2160
- // / very large as we end up creating and destroy constant arrays for each
2161
- // / initialization.
2162
- // / For the above case, we expect the following IR to be generated:
2163
- // /
2164
- // / %struct.U = type { %struct.S*, %struct.S, %struct.U* }
2165
- // / %struct.S = type { i32, i32 }
2166
- // / @e = global %struct.U { %struct.S* gep inbounds (%struct.U, %struct.U* @e,
2167
- // / i64 0, i32 1),
2168
- // / %struct.S { i32 42, i32 84 }, %struct.U* @e }
2169
- // / The %struct.S { i32 42, i32 84 } inner initializer is treated as a complex
2170
- // / constant expression, while the other two elements of @e are "simple".
2171
- static void BatchCommitValueTo (const DenseMap<Constant*, Constant*> &Mem) {
2172
- SmallVector<std::pair<GlobalVariable*, Constant*>, 32 > GVs;
2173
- SmallVector<std::pair<ConstantExpr*, Constant*>, 32 > ComplexCEs;
2174
- SmallVector<std::pair<ConstantExpr*, Constant*>, 32 > SimpleCEs;
2175
- SimpleCEs.reserve (Mem.size ());
2176
-
2177
- for (const auto &I : Mem) {
2178
- if (auto *GV = dyn_cast<GlobalVariable>(I.first )) {
2179
- GVs.push_back (std::make_pair (GV, I.second ));
2180
- } else {
2181
- ConstantExpr *GEP = cast<ConstantExpr>(I.first );
2182
- // We don't handle the deeply recursive case using the batch method.
2183
- if (GEP->getNumOperands () > 3 )
2184
- ComplexCEs.push_back (std::make_pair (GEP, I.second ));
2185
- else
2186
- SimpleCEs.push_back (std::make_pair (GEP, I.second ));
2187
- }
2188
- }
2189
-
2190
- // The algorithm below doesn't handle cases like nested structs, so use the
2191
- // slower fully general method if we have to.
2192
- for (auto ComplexCE : ComplexCEs)
2193
- CommitValueTo (ComplexCE.second , ComplexCE.first );
2194
-
2195
- for (auto GVPair : GVs) {
2196
- assert (GVPair.first ->hasInitializer ());
2197
- GVPair.first ->setInitializer (GVPair.second );
2198
- }
2199
-
2200
- if (SimpleCEs.empty ())
2201
- return ;
2202
-
2203
- // We cache a single global's initializer elements in the case where the
2204
- // subsequent address/val pair uses the same one. This avoids throwing away and
2205
- // rebuilding the constant struct/vector/array just because one element is
2206
- // modified at a time.
2207
- SmallVector<Constant *, 32 > Elts;
2208
- Elts.reserve (SimpleCEs.size ());
2209
- GlobalVariable *CurrentGV = nullptr ;
2210
-
2211
- auto commitAndSetupCache = [&](GlobalVariable *GV, bool Update) {
2212
- Constant *Init = GV->getInitializer ();
2213
- Type *Ty = Init->getType ();
2214
- if (Update) {
2215
- if (CurrentGV) {
2216
- assert (CurrentGV && " Expected a GV to commit to!" );
2217
- Type *CurrentInitTy = CurrentGV->getInitializer ()->getType ();
2218
- // We have a valid cache that needs to be committed.
2219
- if (StructType *STy = dyn_cast<StructType>(CurrentInitTy))
2220
- CurrentGV->setInitializer (ConstantStruct::get (STy, Elts));
2221
- else if (ArrayType *ArrTy = dyn_cast<ArrayType>(CurrentInitTy))
2222
- CurrentGV->setInitializer (ConstantArray::get (ArrTy, Elts));
2223
- else
2224
- CurrentGV->setInitializer (ConstantVector::get (Elts));
2225
- }
2226
- if (CurrentGV == GV)
2227
- return ;
2228
- // Need to clear and set up cache for new initializer.
2229
- CurrentGV = GV;
2230
- Elts.clear ();
2231
- unsigned NumElts;
2232
- if (auto *STy = dyn_cast<StructType>(Ty))
2233
- NumElts = STy->getNumElements ();
2234
- else if (auto *ATy = dyn_cast<ArrayType>(Ty))
2235
- NumElts = ATy->getNumElements ();
2236
- else
2237
- NumElts = cast<FixedVectorType>(Ty)->getNumElements ();
2238
- for (unsigned i = 0 , e = NumElts; i != e; ++i)
2239
- Elts.push_back (Init->getAggregateElement (i));
2240
- }
2241
- };
2242
-
2243
- for (auto CEPair : SimpleCEs) {
2244
- ConstantExpr *GEP = CEPair.first ;
2245
- Constant *Val = CEPair.second ;
2246
-
2247
- GlobalVariable *GV = cast<GlobalVariable>(GEP->getOperand (0 ));
2248
- commitAndSetupCache (GV, GV != CurrentGV);
2249
- ConstantInt *CI = cast<ConstantInt>(GEP->getOperand (2 ));
2250
- Elts[CI->getZExtValue ()] = Val;
2251
- }
2252
- // The last initializer in the list needs to be committed, others
2253
- // will be committed on a new initializer being processed.
2254
- commitAndSetupCache (CurrentGV, true );
2255
- }
2256
-
2257
2069
// / Evaluate static constructors in the function, if we can. Return true if we
2258
2070
// / can, false otherwise.
2259
2071
static bool EvaluateStaticConstructor (Function *F, const DataLayout &DL,
@@ -2268,10 +2080,12 @@ static bool EvaluateStaticConstructor(Function *F, const DataLayout &DL,
2268
2080
++NumCtorsEvaluated;
2269
2081
2270
2082
// We succeeded at evaluation: commit the result.
2083
+ auto NewInitializers = Eval.getMutatedInitializers ();
2271
2084
LLVM_DEBUG (dbgs () << " FULLY EVALUATED GLOBAL CTOR FUNCTION '"
2272
- << F->getName () << " ' to "
2273
- << Eval.getMutatedMemory ().size () << " stores.\n " );
2274
- BatchCommitValueTo (Eval.getMutatedMemory ());
2085
+ << F->getName () << " ' to " << NewInitializers.size ()
2086
+ << " stores.\n " );
2087
+ for (const auto &Pair : NewInitializers)
2088
+ Pair.first ->setInitializer (Pair.second );
2275
2089
for (GlobalVariable *GV : Eval.getInvariants ())
2276
2090
GV->setConstant (true );
2277
2091
}
0 commit comments