Commit Graph

134 Commits

Author SHA1 Message Date
Nate Chandler
a9fe8735e5 [Gardening] Addressed typo. 2022-05-21 12:56:50 -07:00
Rintaro Ishizaki
7486cd1c21 [SwiftCompiler] Move common bridging facilities to 'Basic'
A preparation for AST/DiagnosticEngine bridging
2022-02-20 22:06:39 -08:00
Andrew Trick
83b01d8ebe Improve the SILPhiArgument API
This subclass of SILArgument should be eliminated--it's not always a
phi, and whether it is a "phi argument" has nothing whatsoever to do
with the opcode. That is a property of a value's uses, not a property of the
value.

Until then, provide a logical and useful API within the type. This
often avoids the need to explicitly cast to a SILPhiArgument type and
avoids a lot of boilerplate in code that deals with phis.

Note: PhiOperand and PhiValue are improved abstractions on top of this
API. But the SILArgument-level API is still an important bridge
between SILArgument and other phi abstractions.
2022-02-15 13:28:46 -08:00
Nate Chandler
45afec6e0a [SIL] Added SILBasicBlock::hasPhi. 2022-02-14 17:12:47 -08:00
Konrad `ktoso` Malawski
d96cb1dbaf [SIL] Allow giving debug names to SILBasicBlocks 2022-02-01 14:35:03 +09:00
Erik Eckstein
8080465e77 libswift: basic SIL and SIL bridging
This is the initial version of a buildable SIL definition in libswift.
It defines an initial set of SIL classes, like Function, BasicBlock, Instruction, Argument, and a few instruction classes.
The interface between C++ and SIL is a bridging layer, implemented in C.
It contains all the required bridging data structures used to access various SIL data structures.
2021-06-09 11:28:57 +02:00
Erik Eckstein
24799e1526 SIL: defer instruction deletion to the end of a pass run.
When an instruction is "deleted" from the SIL, it is put into the SILModule::scheduledForDeletion list.
The instructions in this list are eventually deleted for real in SILModule::flushDeletedInsts(), which is called by the pass manager after each pass run.
In other words: instruction deletion is deferred to the end of a pass.

This avoids dangling instruction pointers within the run of a pass and in analysis caches.
Note that the analysis invalidation mechanism ensures that analysis caches are invalidated before flushDeletedInsts().
2021-05-26 21:57:54 +02:00
Andrew Trick
b3e76ae8e5 Add PhiOperand and PhiValue types.
This is necessitated by the SILArgument representation. It has the
tragic property that adding unrelated phis invalidates existing
phis. Therefore, the optimizer can't do book-keeping of phi values by
refering directly to SILValues or Operands. Instead, it must only
refer to SILBasicBlocks and argument indices.
2021-02-01 20:15:05 -08:00
Erik Eckstein
6713c0feca SIL: a few small changes in BasicBlockData
* Instead of passing the vector type as template argument, use a SmallVector and just pass the inline size
* Increase the inline size to 32. Found by experiment, this fits 90% of all functions.
* add an API for getting data for newly created blocks.
2021-01-22 12:53:26 +01:00
Erik Eckstein
47c596d645 SIL: Use TinyPtrVector for the argument list in SILBasicBlock
A TinyPtrVector is the right choice, because ~98% of blocks have 0 or 1 arguments.
2021-01-22 10:05:09 +01:00
Erik Eckstein
2c7027da97 SIL: fix a header-file layering violation: SILArgument.h should not include SILFunction.h
"Containers" should include their "content" and not the other way round.
Also, remove some unused stuff of SILArgument.
2021-01-22 10:05:09 +01:00
Erik Eckstein
65976fd0c5 SIL: add a utility which can manage per-block bitfields and flags efficiently.
It is very efficient: no memory allocation is needed an initialization is at zero cost.
2021-01-21 21:31:41 +01:00
Erik Eckstein
273bd35061 SIL: add a utility which let's manage per-block data efficiently.
It can be used by transforms to store temporary data per basic block.
It is very efficient: only a single memory allocation is needed and no maps are used to lookup data.
2021-01-20 16:09:01 +01:00
Erik Eckstein
b7351780f7 SIL: move all the block-list modifying APIs to SILFunction.
... and remove SILFunction::getBlocks().

It's just a cleanup, NFC.
2021-01-14 17:35:31 +01:00
Erik Eckstein
d824fd3440 DiagnoseInfiniteRecursion: handle invariant conditions and improve the warning message
The main change is to detect infinite recursive calls under invariant conditions. For example:

  func f() {
    if #available(macOS 10.4.4, *) {
      f()
    }
  }

or invariant conditions due to forwarded arguments:

  func f(_ x: Int) {
    if x > 0 {
      f(x)
    }
  }

Also, improve the warning message. Instead of giving a warning at the function location

  warning: all paths through this function will call itself

give a warning at the call location:

  warning: function call causes an infinite recursion

Especially in case of multiple recursive calls, it makes it easier to locate the problem.

https://bugs.swift.org/browse/SR-11842
rdar://57460599
2021-01-13 14:35:03 +01:00
Erik Eckstein
170d9e9eea SIL: Let SILGlobalVariables be destroyed.
This fixes a memory leak: instructions of the static initializer block were not be freed.

rdar://problem/66931238
2020-09-11 11:09:29 +02:00
zoecarver
db553f2f04 [NFC] Remove ostream argument from SILBasicBlock::print.
The first argument, OS, was never used in the SILBasicBlock::print method. Keeping it would be misleading.
2020-05-05 11:42:53 -07:00
Erik Eckstein
1de19a1b32 SimplifyCFG: fix a compile time problem with block merging
When merging many blocks to a single block (in the wrong order), instructions are getting moved over and over again.
This is quadratic and can result in very long compile times for large functions.
To fix this, always move the instruction to smaller block to the larger block.

rdar://problem/56268570
2020-04-10 20:10:24 +02:00
Saleem Abdulrasool
01d5652999 remove VS2015 workaround (NFC)
VS2015 had an issue with the deletion of an operator.  Since VS2017 is
the minimum version that LLVM uses, we can assume that VS2017+ is in use
(_MSC_VER >= 1910).  Clean up the now defunct workaround.
2019-12-23 11:55:10 -08:00
Michael Gottesman
df47eb2c1f [sil] Use SILNodes.def to define ARGKIND##ArrayRef instead of hard coding names.
I also changed all of the places that vended these to use SILNodes.def as well
so that when new argument kinds are added, things just work.
2019-12-02 14:39:02 -08:00
Arnold Schwaighofer
9ecda0c574 SIL: Plumb TypeExpansionContext through SIL 2019-11-11 14:21:52 -08:00
Jordan Rose
8b8c88e258 Improve swift::TransformRange enough to delete TransformArrayRef
We have a lot of "transform a range" types already:
llvm::mapped_iterator, swift::TransformRange and
swift::TransformIterator, and swift::ArrayRefView for static
transformations. This gets rid of one more layer without losing
any real functionality.
2019-10-02 10:23:05 -07:00
Michael Gottesman
748bf88bbe [ownership] Convert SILOptimizer/cast_folding.swift to work with ownership and fix all issues exposed. 2019-05-21 09:07:13 -07:00
Adrian Prantl
ff63eaea6f Remove \brief commands from doxygen comments.
We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.

Patch produced by

      for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
2018-12-04 15:45:04 -08:00
Harlan
00cc011621 [SILOptimizer] Don't diagnose infinite recursion if a branch terminates the program (#19781)
* [SILOptimizer] Don't diagnose infinite recursion if a branch terminates the program

This patch augments the infinite recursion checker to not warn if a
branch terminates, but still warns if a branch calls into something with
@_semantics("programtermination_point"). This way, calling fatalError
doesn't disqualify you for the diagnostic, but calling exit does.

This also removes the warning workaround in the standard library, and
annotates the internal _assertionFailure functions as
programtermination_points, so they get this treatment too.

* Fix formatting in SILInstructions.cpp

* Re-add missing test
2018-10-09 09:46:37 -07:00
Graydon Hoare
cc16ddfd13 Revert "[SILOptimizer] Don't diagnose infinite recursion if a branch terminates (#19724)"
This reverts commit e94450e840.

rdar://45080912
2018-10-07 23:54:33 -07:00
Harlan
e94450e840 [SILOptimizer] Don't diagnose infinite recursion if a branch terminates (#19724)
This patch augments the infinite recursion checker to not warn if a
branch terminates, but still warns if a branch calls into something with
`@_semantics("arc.programtermination_point")`. This way, calling `fatalError`
doesn't disqualify you for the diagnostic, but calling `exit` does.

This also removes the warning workaround in the standard library, and
annotates the internal _assertionFailure functions as
`programtermination_point`s, so they get this treatment too.
2018-10-05 19:15:26 -07:00
Michael Gottesman
d57a88af0d [gardening] Rename references to SILPHIArgument => SILPhiArgument. 2018-09-25 22:23:34 -07:00
Michael Gottesman
2d6106aaa7 [sil] Add convenience method TermInst::getSuccessorBlockArguments().
This convenience API enables one to iterate over the array of arguments of each
successor of the terminator.

To implement this I needed to implement SILBasicBlock::getPHIArguments(), so I
also implemented SILBasicBlock::getFunctionArguments().

rdar://44667493
2018-09-21 10:01:35 -07:00
John McCall
512e55683e Make it easy to create a SILBasicBlock immediately before a target block.
Also, make "after" requests explicit in the API.
2018-08-18 12:36:36 -04:00
swift-ci
b966d3fbc1 Merge remote-tracking branch 'origin/master' into master-next 2018-05-07 08:29:22 -07:00
Jordan Rose
5bf9b9ac76 [SIL] Avoid std::function in transform-iterators
In a non-rigorous test, this change shaves off 20% of the time spent
in SIL optimizations for the standard library in a +Asserts build.
(Admittedly the wins for a no-asserts build will be much lower because
SILInstructionResultArray has a bunch of assertions in its
constructor.)
2018-05-04 17:48:52 -07:00
Bob Wilson
9dc02e67a2 master-next: Stop using ilist_default_traits
LLVM r330736 removed ilist_default_traits. Apparently it is not needed
and ilist_node_traits works just as well.
2018-04-25 22:44:58 -07:00
swift-ci
3e53228828 Merge remote-tracking branch 'origin/master' into master-next 2018-03-28 15:09:15 -07:00
Davide Italiano
dfaf133d27 [LoadableByAddress] Fix debug info holes when expanding alloc_stack.
<rdar://problem/36876376>
2018-03-28 11:54:03 -07:00
Bob Wilson
f9497f5649 master-next: Update phi iteration for the LLVM SSAUpdater change in r321783
This replaces the previous solution that requires non-upstream changes
to LLVM.
2018-01-03 19:08:49 -08:00
Michael Gottesman
7819c4d41a [sil] Add const to int SILBasicBlock::getDebugId().
This is a read only function. This just allows one to call it in more places.

rdar://36032876
2017-12-19 10:10:12 -08:00
Michael Gottesman
2f1ebf3c51 [pred-memopt] Provide normal succ manipulation methods on TermInst instead of SILBasicBlock.
I am doing this for a few different reasons:

1. The code for manipulating successors was partially in TermInst (with
SILBasicBlock delegating to TermInst) and partly in SILBasicBlock itself. It
makes more sense to just be consistent and move all said functionality into
TermInst and just always delegate to SILBasicBlock.

2. I am preparing an API around gathering all critical edges. All of the
critical edge breaking APIs to take a TermInst. I wanted to use some of the
successor APIs, only to discover that we were not delegating to TermInst.  By
moving said functionality onto TermInst itself and delegating, we have it in
both places.

rdar://31521023
2017-11-11 11:27:42 -08:00
John McCall
ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00
Arnold Schwaighofer
3edcd3008d SILBasicBlock: Add moveTo method 2017-09-06 07:24:19 -07:00
Arnold Schwaighofer
1bc5fb193b SIL: Add a utility function to SILBasicBlock to delete its instructions 2017-09-06 07:24:19 -07:00
Erik Eckstein
1ab582e121 SIL: A new representation of static initializers for global variables.
Static initializers are now represented by a list of literal and aggregate instructions in a SILGlobalVariable.
For details see SIL.rst.

This representation is cleaner than what we did so far (point to the initializer function and do some pattern matching).

One implication of that change is that now (a subset of) instructions not necessarily have a parent function.
Regarding the generated code it's a NFC.
Also the swift module format didn't change because so far we don't serializer global variables.
2017-08-23 09:15:01 -07:00
Jordan Rose
c22168d02d [SIL] Implement a very simple isLegalToHoistInto for llvm::LoopInfo.
I'm not a SIL author, so it's likely that this could be improved,
but I think this is closest to the old LLVM behavior.
2017-06-23 12:49:49 -07:00
Michael Gottesman
a11fceb635 [gardening] Remove unneeded method addNodeToList on ilist_traits<SILBasicBlock>.
addNodeToList only needs to be implemented to override the default callback
behavior of ilist_trait_defaults<SILBasicBlock>.  This implmentation in
ilist_traits<SILBasicBlock> is exactly the same as the default callback so is
unnecessary.
2017-06-06 10:12:37 -07:00
Michael Gottesman
e11daa8ddf [upstream-update] Do not use succ_iterator in GraphTraits. Use succblock_iterator instead.
rdar://31790907
2017-04-26 16:50:57 -07:00
Michael Gottesman
913920c93b [sil] Rename SILSuccessorIterator -> SILSuccessor::pred_iterator.
This iterator is not actually a SILSuccessorIterator since it is not iterating
over the "successors" of a block. Instead it is used to given the head of a CFG
edge, iterate over the CFG edge's predecessors using the double linked list
stored inside SILSuccessor.

This rename/refactor ties SILSuccessor closer to SILSuccessorIterator and makes
it clear what we are actually iterating over.
2017-04-26 13:32:59 -07:00
Andrew Trick
2eb6d48b1c [AccessMarker] Fix a reverse instruction iterator.
I reversed this loop's direction over the instruction list and forgot to change
the order of erasing an instruction with respect to advancing the iterator.

Thankfully ASAN is far smarter than I.

Converting between forward/reverse iterators makes the loop unreadable.
Add an iterator return value to BasicBlock::erase(SILInstruction*).
2017-04-10 14:08:59 -07:00
Andrew Trick
7ea54c8927 SILPrintContext: support for printing consistent block numbers. 2017-04-05 19:59:15 -07:00
Michael Gottesman
79b225ffa8 [silgen] Fix up EnumElementPatternInitialization::emitEnumMatch to use ownership.
This commit does a few things:

1. It uses SwitchEnumBuilder so we are not re-inventing any wheels.
2. Instead of hacking around not putting in a destroy for .None on the fail
pass, just *do the right thing* and recognize that we have a binary case enum
and in such a case, just emit code for the other case rather than use a default
case (meaning no cleanup on .none).

rdar://31145255
2017-03-29 15:36:41 -07:00
Michael Gottesman
ed67bf9f21 [ownership-verifier] Teach the ownership verifier how to handle unreachable code.
There are a few different use cases here:

1. In Raw SIL, no return folding may not have been run yet implying that a call
to a no-return function /can/ have arbitrary control flow after it (consider
mandatory inlined functions). We need to recognize that the region of code that
is strictly post dominated by the no-return function is "transitively
unreachable" and thus leaking is ok from that point. *Footnote 1*.

2. In Canonical and Raw SIL, we must recognize that unreachables and no-return
functions constitute places where we are allowed to leak.

rdar://29791263

----

*Footnote 1*: The reason why this is done is since we want to emit unreachable
code diagnostics when we run no-return folding. By leaving in the relevant code,
we have preserved all of the SILLocations on that code allowing us to create
really nice diagnostics.
2017-02-13 16:36:01 -08:00