@@ -86,116 +86,6 @@ SILInstruction *SILGlobalVariable::getStaticInitializerValue() {
8686 return &StaticInitializerBlock.back ();
8787}
8888
89- BuiltinInst *SILGlobalVariable::getOffsetSubtract (const TupleExtractInst *TE,
90- SILModule &M) {
91-
92- // Match the pattern:
93- // tuple_extract(usub_with_overflow(x, integer_literal, integer_literal 0), 0)
94-
95- if (TE->getFieldIndex () != 0 )
96- return nullptr ;
97-
98- auto *BI = dyn_cast<BuiltinInst>(TE->getOperand ());
99- if (!BI)
100- return nullptr ;
101- if (M.getBuiltinInfo (BI->getName ()).ID != BuiltinValueKind::USubOver)
102- return nullptr ;
103-
104- if (!isa<IntegerLiteralInst>(BI->getArguments ()[1 ]))
105- return nullptr ;
106-
107- auto *overflowFlag = dyn_cast<IntegerLiteralInst>(BI->getArguments ()[2 ]);
108- if (!overflowFlag || !overflowFlag->getValue ().isNullValue ())
109- return nullptr ;
110-
111- return BI;
112- }
113-
114- bool SILGlobalVariable::isValidStaticInitializerInst (const SILInstruction *I,
115- SILModule &M) {
116- for (const Operand &op : I->getAllOperands ()) {
117- // Rule out SILUndef and SILArgument.
118- if (!isa<SingleValueInstruction>(op.get ()))
119- return false ;
120- }
121- switch (I->getKind ()) {
122- case SILInstructionKind::BuiltinInst: {
123- auto *bi = cast<BuiltinInst>(I);
124- switch (M.getBuiltinInfo (bi->getName ()).ID ) {
125- case BuiltinValueKind::ZeroInitializer: {
126- auto type = bi->getType ().getASTType ();
127- if (auto vector = dyn_cast<BuiltinVectorType>(type))
128- type = vector.getElementType ();
129- return isa<BuiltinIntegerType>(type) || isa<BuiltinFloatType>(type);
130- }
131- case BuiltinValueKind::PtrToInt:
132- if (isa<LiteralInst>(bi->getArguments ()[0 ]))
133- return true ;
134- break ;
135- case BuiltinValueKind::StringObjectOr:
136- // The first operand can be a string literal (i.e. a pointer), but the
137- // second operand must be a constant. This enables creating a
138- // a pointer+offset relocation.
139- // Note that StringObjectOr requires the or'd bits in the first
140- // operand to be 0, so the operation is equivalent to an addition.
141- if (isa<IntegerLiteralInst>(bi->getArguments ()[1 ]))
142- return true ;
143- break ;
144- case BuiltinValueKind::ZExtOrBitCast:
145- return true ;
146- case BuiltinValueKind::USubOver: {
147- // Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
148- // This pattern appears in UTF8 String literal construction.
149- auto *TE = bi->getSingleUserOfType <TupleExtractInst>();
150- return TE && getOffsetSubtract (TE, M);
151- }
152- case BuiltinValueKind::OnFastPath:
153- return true ;
154- default :
155- break ;
156- }
157- return false ;
158- }
159- case SILInstructionKind::TupleExtractInst: {
160- // Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
161- // This pattern appears in UTF8 String literal construction.
162- auto *TE = cast<TupleExtractInst>(I);
163- if (!getOffsetSubtract (TE, M))
164- return false ;
165- auto *BI = TE->getSingleUserOfType <BuiltinInst>();
166- return BI &&
167- M.getBuiltinInfo (BI->getName ()).ID == BuiltinValueKind::StringObjectOr;
168- }
169- case SILInstructionKind::StringLiteralInst:
170- switch (cast<StringLiteralInst>(I)->getEncoding ()) {
171- case StringLiteralInst::Encoding::Bytes:
172- case StringLiteralInst::Encoding::UTF8:
173- return true ;
174- case StringLiteralInst::Encoding::ObjCSelector:
175- // Objective-C selector string literals cannot be used in static
176- // initializers.
177- return false ;
178- }
179- return false ;
180- case SILInstructionKind::FunctionRefInst:
181- // TODO: support async function pointers in static globals.
182- if (cast<FunctionRefInst>(I)->getReferencedFunction ()->isAsync ())
183- return false ;
184- return true ;
185- case SILInstructionKind::StructInst:
186- case SILInstructionKind::TupleInst:
187- case SILInstructionKind::IntegerLiteralInst:
188- case SILInstructionKind::FloatLiteralInst:
189- case SILInstructionKind::ObjectInst:
190- case SILInstructionKind::ValueToBridgeObjectInst:
191- case SILInstructionKind::ConvertFunctionInst:
192- case SILInstructionKind::ThinToThickFunctionInst:
193- return true ;
194- default :
195- return false ;
196- }
197- }
198-
19989// / Return whether this variable corresponds to a Clang node.
20090bool SILGlobalVariable::hasClangNode () const {
20191 return (VDecl ? VDecl->hasClangNode () : false );
@@ -244,11 +134,7 @@ SILGlobalVariable *swift::getVariableOfGlobalInit(SILFunction *AddrF) {
244134 if (!InitF)
245135 return nullptr ;
246136
247- // If the globalinit_func is trivial, continue; otherwise bail.
248- SingleValueInstruction *dummyInitVal;
249- auto *SILG = getVariableOfStaticInitializer (InitF, dummyInitVal);
250-
251- return SILG;
137+ return getVariableOfStaticInitializer (InitF);
252138}
253139
254140SILFunction *swift::getCalleeOfOnceCall (BuiltinInst *BI) {
@@ -297,48 +183,17 @@ SILFunction *swift::findInitializer(SILFunction *AddrF,
297183 return callee;
298184}
299185
300- SILGlobalVariable *
301- swift::getVariableOfStaticInitializer (SILFunction *InitFunc,
302- SingleValueInstruction *&InitVal) {
303- InitVal = nullptr ;
304- SILGlobalVariable *GVar = nullptr ;
186+ SILGlobalVariable *swift::getVariableOfStaticInitializer (SILFunction *InitFunc) {
305187 // We only handle a single SILBasicBlock for now.
306188 if (InitFunc->size () != 1 )
307189 return nullptr ;
308190
309- SILBasicBlock *BB = &InitFunc->front ();
310- GlobalAddrInst *SGA = nullptr ;
311- bool HasStore = false ;
312- for (auto &I : *BB) {
313- // Make sure we have a single GlobalAddrInst and a single StoreInst.
314- // And the StoreInst writes to the GlobalAddrInst.
315- if (isa<AllocGlobalInst>(&I) || isa<ReturnInst>(&I)
316- || isa<DebugValueInst>(&I) || isa<DebugStepInst>(&I)) {
317- continue ;
318- } else if (auto *sga = dyn_cast<GlobalAddrInst>(&I)) {
319- if (SGA)
320- return nullptr ;
321- SGA = sga;
322- GVar = SGA->getReferencedGlobal ();
323- } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
324- if (HasStore || SI->getDest () != SGA)
325- return nullptr ;
326- HasStore = true ;
327- InitVal = cast<SingleValueInstruction>(SI->getSrc ());
328- } else if (auto *mt = dyn_cast<MetatypeInst>(&I)) {
329- // Unused meta_type instructions are sometimes generated by SILGen.
330- // Handle this case to not require to run DeadCodeElimination before
331- // MandatoryGlobalOpt.
332- if (!mt->use_empty ())
333- return nullptr ;
334- } else if (!SILGlobalVariable::isValidStaticInitializerInst (&I,
335- I.getModule ())) {
336- return nullptr ;
191+ for (auto &inst : InitFunc->front ()) {
192+ if (auto *agi = dyn_cast<AllocGlobalInst>(&inst)) {
193+ return agi->getReferencedGlobal ();
337194 }
338195 }
339- if (!InitVal)
340- return nullptr ;
341- return GVar;
196+ return nullptr ;
342197}
343198
344199SILType
0 commit comments