|
113 | 113 | #include "llvm/Analysis/CFG.h"
|
114 | 114 | #include "clang/CodeGen/SwiftCallingConv.h"
|
115 | 115 |
|
116 |
| -#include "IRGenModule.h" |
117 |
| -#include "LoadableTypeInfo.h" |
118 |
| -#include "NonFixedTypeInfo.h" |
119 |
| -#include "ResilientTypeInfo.h" |
120 | 116 | #include "GenMeta.h"
|
121 | 117 | #include "GenProto.h"
|
122 | 118 | #include "GenType.h"
|
123 | 119 | #include "IRGenDebugInfo.h"
|
| 120 | +#include "IRGenModule.h" |
| 121 | +#include "LoadableTypeInfo.h" |
| 122 | +#include "NonFixedTypeInfo.h" |
| 123 | +#include "ResilientTypeInfo.h" |
124 | 124 | #include "ScalarTypeInfo.h"
|
125 | 125 | #include "StructLayout.h"
|
| 126 | +#include "SwitchBuilder.h" |
126 | 127 |
|
127 | 128 | using namespace swift;
|
128 | 129 | using namespace irgen;
|
@@ -239,190 +240,6 @@ irgen::EnumImplStrategy::getResilientTagIndex(EnumElementDecl *Case) const {
|
239 | 240 | }
|
240 | 241 |
|
241 | 242 | namespace {
|
242 |
| - /// A builder that produces an LLVM branch or switch instruction for a set |
243 |
| - /// of destinations. |
244 |
| - class SwitchBuilder { |
245 |
| - private: |
246 |
| -#ifndef NDEBUG |
247 |
| - /// Track whether we added as many cases as we expected to. |
248 |
| - unsigned CasesToAdd; |
249 |
| -#endif |
250 |
| - |
251 |
| - protected: |
252 |
| - IRBuilder Builder; |
253 |
| - llvm::Value *Subject; |
254 |
| - |
255 |
| - /// Protected initializer. Clients should use the `create` factory method. |
256 |
| - SwitchBuilder(IRGenFunction &IGF, llvm::Value *Subject, unsigned NumCases) |
257 |
| - : |
258 |
| -#ifndef NDEBUG |
259 |
| - CasesToAdd(NumCases), |
260 |
| -#endif |
261 |
| - // Create our own IRBuilder, so that the SwitchBuilder is always able to |
262 |
| - // generate the branch instruction at the right point, even if it needs |
263 |
| - // to collect multiple cases before building an instruction. |
264 |
| - Builder(IGF.IGM.getLLVMContext(), /*DebugInfo*/ false), Subject(Subject) |
265 |
| - { |
266 |
| - // Start our builder off at IGF's current insertion point. |
267 |
| - Builder.SetInsertPoint(IGF.Builder.GetInsertBlock(), |
268 |
| - IGF.Builder.GetInsertPoint()); |
269 |
| - } |
270 |
| - |
271 |
| - public: |
272 |
| -#ifndef NDEBUG |
273 |
| - virtual ~SwitchBuilder() { |
274 |
| - assert(CasesToAdd == 0 && "Did not add enough cases"); |
275 |
| - } |
276 |
| -#endif |
277 |
| - |
278 |
| - // Create a SwitchBuilder instance for a switch that will have the given |
279 |
| - // number of cases. |
280 |
| - static std::unique_ptr<SwitchBuilder> |
281 |
| - create(IRGenFunction &IGF, llvm::Value *Subject, |
282 |
| - SwitchDefaultDest Default, |
283 |
| - unsigned NumCases); |
284 |
| - |
285 |
| - /// Add a case to the switch. |
286 |
| - virtual void addCase(llvm::ConstantInt *value, llvm::BasicBlock *dest) { |
287 |
| -#ifndef NDEBUG |
288 |
| - assert(CasesToAdd > 0 && "Added too many cases"); |
289 |
| - --CasesToAdd; |
290 |
| -#endif |
291 |
| - } |
292 |
| - }; |
293 |
| - |
294 |
| - /// A builder that emits an unconditional branch for a "switch" with only |
295 |
| - /// one destination. |
296 |
| - class BrSwitchBuilder final : public SwitchBuilder { |
297 |
| - private: |
298 |
| - friend class SwitchBuilder; |
299 |
| - |
300 |
| - BrSwitchBuilder(IRGenFunction &IGF, llvm::Value *Subject, unsigned NumCases) |
301 |
| - : SwitchBuilder(IGF, Subject, NumCases) |
302 |
| - { |
303 |
| - assert(NumCases == 1 && "should have only one branch"); |
304 |
| - } |
305 |
| - |
306 |
| - public: |
307 |
| - void addCase(llvm::ConstantInt *value, llvm::BasicBlock *dest) override { |
308 |
| - SwitchBuilder::addCase(value, dest); |
309 |
| - Builder.CreateBr(dest); |
310 |
| - } |
311 |
| - }; |
312 |
| - |
313 |
| - /// A builder that produces a conditional branch for a "switch" with two |
314 |
| - /// defined destinations. |
315 |
| - class CondBrSwitchBuilder final : public SwitchBuilder { |
316 |
| - private: |
317 |
| - friend class SwitchBuilder; |
318 |
| - llvm::BasicBlock *FirstDest; |
319 |
| - |
320 |
| - CondBrSwitchBuilder(IRGenFunction &IGF, llvm::Value *Subject, |
321 |
| - SwitchDefaultDest Default, |
322 |
| - unsigned NumCases) |
323 |
| - : SwitchBuilder(IGF, Subject, NumCases), |
324 |
| - FirstDest(Default.getInt() == IsUnreachable |
325 |
| - ? nullptr : Default.getPointer()) |
326 |
| - { |
327 |
| - assert(NumCases + (Default.getInt() == IsNotUnreachable) == 2 |
328 |
| - && "should have two branches total"); |
329 |
| - } |
330 |
| - |
331 |
| - public: |
332 |
| - void addCase(llvm::ConstantInt *value, llvm::BasicBlock *dest) override { |
333 |
| - SwitchBuilder::addCase(value, dest); |
334 |
| - |
335 |
| - // If we don't have a first destination yet, save it. |
336 |
| - // We don't need to save the value in this case since we assume that the |
337 |
| - // subject must be one of the case values. We only have to test one or |
338 |
| - // the other. |
339 |
| - // |
340 |
| - // TODO: It may make sense to save both case values, and pick which one |
341 |
| - // to compare based on which value is more likely to be efficiently |
342 |
| - // representable in the target machine language. For example, zero |
343 |
| - // or a small immediate is usually cheaper to materialize than a larger |
344 |
| - // value that may require multiple instructions or a bigger encoding. |
345 |
| - if (!FirstDest) { |
346 |
| - FirstDest = dest; |
347 |
| - return; |
348 |
| - } |
349 |
| - |
350 |
| - // Otherwise, we have both destinations for the branch and a value to |
351 |
| - // test against. We can make the instruction now. |
352 |
| - if (cast<llvm::IntegerType>(Subject->getType())->getBitWidth() == 1) { |
353 |
| - // If the subject is already i1, we can use it directly as the branch |
354 |
| - // condition. |
355 |
| - if (value->isZero()) |
356 |
| - Builder.CreateCondBr(Subject, FirstDest, dest); |
357 |
| - else |
358 |
| - Builder.CreateCondBr(Subject, dest, FirstDest); |
359 |
| - return; |
360 |
| - } |
361 |
| - // Otherwise, compare against the case value we have. |
362 |
| - auto test = Builder.CreateICmpNE(Subject, value); |
363 |
| - Builder.CreateCondBr(test, FirstDest, dest); |
364 |
| - } |
365 |
| - }; |
366 |
| - |
367 |
| - /// A builder that produces a switch instruction for a switch with many |
368 |
| - /// destinations. |
369 |
| - class SwitchSwitchBuilder final : public SwitchBuilder { |
370 |
| - private: |
371 |
| - friend class SwitchBuilder; |
372 |
| - llvm::SwitchInst *TheSwitch; |
373 |
| - |
374 |
| - SwitchSwitchBuilder(IRGenFunction &IGF, llvm::Value *Subject, |
375 |
| - SwitchDefaultDest Default, |
376 |
| - unsigned NumCases) |
377 |
| - : SwitchBuilder(IGF, Subject, NumCases) |
378 |
| - { |
379 |
| - TheSwitch = IGF.Builder.CreateSwitch(Subject, Default.getPointer(), |
380 |
| - NumCases); |
381 |
| - } |
382 |
| - |
383 |
| - public: |
384 |
| - void addCase(llvm::ConstantInt *value, llvm::BasicBlock *dest) override { |
385 |
| - SwitchBuilder::addCase(value, dest); |
386 |
| - TheSwitch->addCase(value, dest); |
387 |
| - } |
388 |
| - }; |
389 |
| - |
390 |
| - std::unique_ptr<SwitchBuilder> |
391 |
| - SwitchBuilder::create(IRGenFunction &IGF, llvm::Value *Subject, |
392 |
| - SwitchDefaultDest Default, unsigned NumCases) { |
393 |
| - // Pick a builder based on how many total reachable destinations we intend |
394 |
| - // to have. |
395 |
| - switch (NumCases + (Default.getInt() == IsNotUnreachable)) { |
396 |
| - case 0: |
397 |
| - // No reachable destinations. We can emit an unreachable and go about |
398 |
| - // our business. |
399 |
| - IGF.Builder.CreateUnreachable(); |
400 |
| - return nullptr; |
401 |
| - case 1: |
402 |
| - // One reachable destination. We can emit an unconditional branch. |
403 |
| - // If that one branch is the default, we're done. |
404 |
| - if (Default.getInt() == IsNotUnreachable) { |
405 |
| - IGF.Builder.CreateBr(Default.getPointer()); |
406 |
| - return nullptr; |
407 |
| - } |
408 |
| - |
409 |
| - // Otherwise, use a builder to emit the one case. |
410 |
| - return std::unique_ptr<SwitchBuilder>( |
411 |
| - new BrSwitchBuilder(IGF, Subject, NumCases)); |
412 |
| - case 2: |
413 |
| - // Two reachable destinations. We can emit a single conditional branch. |
414 |
| - return std::unique_ptr<SwitchBuilder>( |
415 |
| - new CondBrSwitchBuilder(IGF, Subject, Default, NumCases)); |
416 |
| - default: |
417 |
| - // Anything more, fall over into a switch. |
418 |
| - // TODO: Since fast isel doesn't support switch insns, we may want to |
419 |
| - // also support a "pre-lowered-switch" builder that builds a jump tree |
420 |
| - // for unoptimized builds. |
421 |
| - return std::unique_ptr<SwitchBuilder>( |
422 |
| - new SwitchSwitchBuilder(IGF, Subject, Default, NumCases)); |
423 |
| - } |
424 |
| - } |
425 |
| - |
426 | 243 | /// Implementation strategy for singleton enums, with zero or one cases.
|
427 | 244 | class SingletonEnumImplStrategy final : public EnumImplStrategy {
|
428 | 245 | bool needsPayloadSizeInMetadata() const override { return false; }
|
|
0 commit comments