I am going to use this to refactor a bunch of the goop in the cast optimizer. At
a high level, we are really just performing a giant switch over the casts to
grab different state. We then take that state and we pass it into the bridge
cast optimizer.
To make such code more compact/easier to understand, I am adding in this commit
a type erased dynamic cast instruction type called "SILDynamicCastInst". In
subsequent commits, I wire up each of the individual instructions to it one at a
time.
As an additional advantage it will enable us to take advantage of covered
switches when ever in the future we introduce new casts.
replace value uses action to make sure that we properly notify passes that we
made the change.
This fixes a latent bug where we were not notifying SILCombine about this
replacement.
Specifically:
- auto replaceCast = [&](SingleValueInstruction *NewCast) {
- assert(Ty.getAs<AnyMetatypeType>()->getRepresentation()
- == NewCast->getType().getAs<AnyMetatypeType>()->getRepresentation());
- MCI->replaceAllUsesWith(NewCast);
- EraseInstAction(MCI);
- return NewCast;
+ auto replaceCast = [&](SILValue newValue) -> SILValue {
+ assert(ty.getAs<AnyMetatypeType>()->getRepresentation() ==
+ newValue->getType().getAs<AnyMetatypeType>()->getRepresentation());
+ ReplaceValueUsesAction(mci, newValue);
+ EraseInstAction(mci);
+ return newValue;
};
Notice how we use MCI->replaceAllUsesWith instead of one of our replace call
backs. SILCombine hooks these to know if it should re-run users.
NOTE: I changed all places that the CastOptimizer is created to just pass in
nullptr for now so this is NFC.
----
Right now the interface of the CastOptimizer is muddled and confused. Sometimes
it is returning a value that should be used by the caller, other times it is
returning an instruction that is meant to be reprocessed by the caller.
This series of patches is attempting to clean this up by switching to the
following model:
1. If we are optimizing a cast of a value, we return a SILValue. If the cast
fails, we return an empty SILValue().
2. If we are optimizing a cast of an address, we return a boolean value to show
success/failure and require the user to use the SILBuilderContext to get the
cast if they need to.
This cannot be correctly done as a SILCombine because it must create
new instructions at a previous location. Move the optimization into
CastOptimizer. Insert the new metatype instructions in the correct
spot. And manually do the replaceAllUsesWith and eraseInstruction
steps.
Fixes <rdar://problem/46746188> crash in swift_getObjCClassFromObject.
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
I am going to add the code in a bit that does the notifications. I tried to pass
down the builder instead of the pass manager. I also tried not to change the
formatting.
rdar://42301529
Local.cpp was ~3k lines of which 1.5k (i.e. 1/2) was the cast optimizer. This
commit extracts the cast optimizer into its own .cpp and .h file. It is large
enough to stand on its own and allows for Local.cpp to return to being a small
group of helper functions.
I am making some changes in this area due to the change in certain function
conventions caused by the +0-normal-arg work. I am just trying to leave the area
a little cleaner than before.