IR: refactor PhaseBuilders a little

- use named classes to improve stacktraces
- reorder parameters to make the code shorter
- use explicit types to improve IDE resolve in usages
This commit is contained in:
Alexander Udalov
2020-07-01 02:21:56 +02:00
parent 7997d4afd3
commit 4475325ffa
@@ -58,17 +58,10 @@ fun <Context : CommonBackendContext> namedIrModulePhase(
stickyPostconditions: Set<Checker<IrModuleFragment>> = lower.stickyPostconditions, stickyPostconditions: Set<Checker<IrModuleFragment>> = lower.stickyPostconditions,
actions: Set<Action<IrModuleFragment, Context>> = setOf(defaultDumper, validationAction), actions: Set<Action<IrModuleFragment, Context>> = setOf(defaultDumper, validationAction),
nlevels: Int = 1 nlevels: Int = 1
) = NamedCompilerPhase( ): NamedCompilerPhase<Context, IrModuleFragment> =
name, NamedCompilerPhase(
description, name, description, prerequisite, lower, preconditions, postconditions, stickyPostconditions, actions, nlevels
prerequisite, )
lower,
preconditions,
postconditions,
stickyPostconditions,
actions,
nlevels
)
fun <Context : CommonBackendContext> namedIrFilePhase( fun <Context : CommonBackendContext> namedIrFilePhase(
name: String, name: String,
@@ -80,17 +73,10 @@ fun <Context : CommonBackendContext> namedIrFilePhase(
stickyPostconditions: Set<Checker<IrFile>> = lower.stickyPostconditions, stickyPostconditions: Set<Checker<IrFile>> = lower.stickyPostconditions,
actions: Set<Action<IrFile, Context>> = setOf(defaultDumper, validationAction), actions: Set<Action<IrFile, Context>> = setOf(defaultDumper, validationAction),
nlevels: Int = 1 nlevels: Int = 1
) = NamedCompilerPhase( ): NamedCompilerPhase<Context, IrFile> =
name, NamedCompilerPhase(
description, name, description, prerequisite, lower, preconditions, postconditions, stickyPostconditions, actions, nlevels
prerequisite, )
lower,
preconditions,
postconditions,
stickyPostconditions,
actions,
nlevels
)
fun <Context : CommonBackendContext, Element : IrElement> makeCustomPhase( fun <Context : CommonBackendContext, Element : IrElement> makeCustomPhase(
op: (Context, Element) -> Unit, op: (Context, Element) -> Unit,
@@ -102,27 +88,19 @@ fun <Context : CommonBackendContext, Element : IrElement> makeCustomPhase(
stickyPostconditions: Set<Checker<Element>> = emptySet(), stickyPostconditions: Set<Checker<Element>> = emptySet(),
actions: Set<Action<Element, Context>> = setOf(defaultDumper, validationAction), actions: Set<Action<Element, Context>> = setOf(defaultDumper, validationAction),
nlevels: Int = 1 nlevels: Int = 1
) = NamedCompilerPhase( ): NamedCompilerPhase<Context, Element> =
name, NamedCompilerPhase(
description, name, description, prerequisite, CustomPhaseAdapter(op), preconditions, postconditions, stickyPostconditions, actions, nlevels,
prerequisite, )
preconditions = preconditions,
postconditions = postconditions, private class CustomPhaseAdapter<Context : CommonBackendContext, Element>(
stickyPostconditions = stickyPostconditions, private val op: (Context, Element) -> Unit
actions = actions, ) : SameTypeCompilerPhase<Context, Element> {
nlevels = nlevels, override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Element>, context: Context, input: Element): Element {
lower = object : SameTypeCompilerPhase<Context, Element> { op(context, input)
override fun invoke( return input
phaseConfig: PhaseConfig,
phaserState: PhaserState<Element>,
context: Context,
input: Element
): Element {
op(context, input)
return input
}
} }
) }
fun <Context : CommonBackendContext> namedUnitPhase( fun <Context : CommonBackendContext> namedUnitPhase(
name: String, name: String,
@@ -130,11 +108,10 @@ fun <Context : CommonBackendContext> namedUnitPhase(
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet(), prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet(),
nlevels: Int = 1, nlevels: Int = 1,
lower: CompilerPhase<Context, Unit, Unit> lower: CompilerPhase<Context, Unit, Unit>
) = NamedCompilerPhase( ): NamedCompilerPhase<Context, Unit> =
name, description, prerequisite, NamedCompilerPhase(
lower = lower, name, description, prerequisite, lower, nlevels = nlevels
nlevels = nlevels )
)
@Suppress("unused") // Used in kotlin-native @Suppress("unused") // Used in kotlin-native
fun <Context : CommonBackendContext> namedOpUnitPhase( fun <Context : CommonBackendContext> namedOpUnitPhase(
@@ -142,7 +119,7 @@ fun <Context : CommonBackendContext> namedOpUnitPhase(
description: String, description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>>, prerequisite: Set<NamedCompilerPhase<Context, *>>,
op: Context.() -> Unit op: Context.() -> Unit
) = namedUnitPhase( ): NamedCompilerPhase<Context, Unit> = namedUnitPhase(
name, description, prerequisite, name, description, prerequisite,
nlevels = 0, nlevels = 0,
lower = object : SameTypeCompilerPhase<Context, Unit> { lower = object : SameTypeCompilerPhase<Context, Unit> {
@@ -161,35 +138,32 @@ fun <Context : CommonBackendContext> performByIrFile(
stickyPostconditions: Set<Checker<IrModuleFragment>> = emptySet(), stickyPostconditions: Set<Checker<IrModuleFragment>> = emptySet(),
actions: Set<Action<IrModuleFragment, Context>> = setOf(defaultDumper), actions: Set<Action<IrModuleFragment, Context>> = setOf(defaultDumper),
lower: CompilerPhase<Context, IrFile, IrFile> lower: CompilerPhase<Context, IrFile, IrFile>
) = namedIrModulePhase( ): NamedCompilerPhase<Context, IrModuleFragment> =
name, description, prerequisite, namedIrModulePhase(
preconditions = preconditions, name, description, prerequisite, PerformByIrFilePhase(lower), preconditions, postconditions, stickyPostconditions, actions,
postconditions = postconditions, nlevels = 1,
stickyPostconditions = stickyPostconditions, )
actions = actions,
nlevels = 1,
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> {
override fun invoke(
phaseConfig: PhaseConfig,
phaserState: PhaserState<IrModuleFragment>,
context: Context,
input: IrModuleFragment
): IrModuleFragment {
for (irFile in input.files) {
try {
lower.invoke(phaseConfig, phaserState.changeType(), context, irFile)
} catch (e: Throwable) {
CodegenUtil.reportBackendException(e, "IR lowering", irFile.fileEntry.name)
}
}
// TODO: no guarantee that module identity is preserved by `lower` private class PerformByIrFilePhase<Context : CommonBackendContext>(
return input private val lower: CompilerPhase<Context, IrFile, IrFile>
) : SameTypeCompilerPhase<Context, IrModuleFragment> {
override fun invoke(
phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment
): IrModuleFragment {
for (irFile in input.files) {
try {
lower.invoke(phaseConfig, phaserState.changeType(), context, irFile)
} catch (e: Throwable) {
CodegenUtil.reportBackendException(e, "IR lowering", irFile.fileEntry.name)
}
} }
override fun getNamedSubphases(startDepth: Int) = lower.getNamedSubphases(startDepth) // TODO: no guarantee that module identity is preserved by `lower`
return input
} }
)
override fun getNamedSubphases(startDepth: Int) = lower.getNamedSubphases(startDepth)
}
fun <Context : CommonBackendContext> makeIrFilePhase( fun <Context : CommonBackendContext> makeIrFilePhase(
lowering: (Context) -> FileLoweringPass, lowering: (Context) -> FileLoweringPass,
@@ -200,20 +174,20 @@ fun <Context : CommonBackendContext> makeIrFilePhase(
postconditions: Set<Checker<IrFile>> = emptySet(), postconditions: Set<Checker<IrFile>> = emptySet(),
stickyPostconditions: Set<Checker<IrFile>> = emptySet(), stickyPostconditions: Set<Checker<IrFile>> = emptySet(),
actions: Set<Action<IrFile, Context>> = setOf(defaultDumper, validationAction) actions: Set<Action<IrFile, Context>> = setOf(defaultDumper, validationAction)
) = namedIrFilePhase( ): NamedCompilerPhase<Context, IrFile> =
name, description, prerequisite, namedIrFilePhase(
preconditions = preconditions, name, description, prerequisite, FileLoweringPhaseAdapter(lowering), preconditions, postconditions, stickyPostconditions, actions,
postconditions = postconditions, nlevels = 0,
stickyPostconditions = stickyPostconditions, )
actions = actions,
nlevels = 0, private class FileLoweringPhaseAdapter<Context : CommonBackendContext>(
lower = object : SameTypeCompilerPhase<Context, IrFile> { private val lowering: (Context) -> FileLoweringPass
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<IrFile>, context: Context, input: IrFile): IrFile { ) : SameTypeCompilerPhase<Context, IrFile> {
lowering(context).lower(input) override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<IrFile>, context: Context, input: IrFile): IrFile {
return input lowering(context).lower(input)
} return input
} }
) }
fun <Context : CommonBackendContext> makeIrModulePhase( fun <Context : CommonBackendContext> makeIrModulePhase(
lowering: (Context) -> FileLoweringPass, lowering: (Context) -> FileLoweringPass,
@@ -224,39 +198,37 @@ fun <Context : CommonBackendContext> makeIrModulePhase(
postconditions: Set<Checker<IrModuleFragment>> = emptySet(), postconditions: Set<Checker<IrModuleFragment>> = emptySet(),
stickyPostconditions: Set<Checker<IrModuleFragment>> = emptySet(), stickyPostconditions: Set<Checker<IrModuleFragment>> = emptySet(),
actions: Set<Action<IrModuleFragment, Context>> = setOf(defaultDumper, validationAction) actions: Set<Action<IrModuleFragment, Context>> = setOf(defaultDumper, validationAction)
) = namedIrModulePhase( ): NamedCompilerPhase<Context, IrModuleFragment> =
name, description, prerequisite, namedIrModulePhase(
preconditions = preconditions, name, description, prerequisite, ModuleLoweringPhaseAdapter(lowering), preconditions, postconditions, stickyPostconditions, actions,
postconditions = postconditions, nlevels = 0,
stickyPostconditions = stickyPostconditions, )
actions = actions,
nlevels = 0, private class ModuleLoweringPhaseAdapter<Context : CommonBackendContext>(
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> { private val lowering: (Context) -> FileLoweringPass
override fun invoke( ) : SameTypeCompilerPhase<Context, IrModuleFragment> {
phaseConfig: PhaseConfig, override fun invoke(
phaserState: PhaserState<IrModuleFragment>, phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment
context: Context, ): IrModuleFragment {
input: IrModuleFragment lowering(context).lower(input)
): IrModuleFragment { return input
lowering(context).lower(input)
return input
}
} }
) }
@Suppress("unused") // Used in kotlin-native @Suppress("unused") // Used in kotlin-native
fun <Context : CommonBackendContext, Input> unitSink() = object : CompilerPhase<Context, Input, Unit> { fun <Context : CommonBackendContext, Input> unitSink(): CompilerPhase<Context, Input, Unit> =
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Input>, context: Context, input: Input) {} object : CompilerPhase<Context, Input, Unit> {
} override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Input>, context: Context, input: Input) {}
}
// Intermediate phases to change the object of transformations // Intermediate phases to change the object of transformations
@Suppress("unused") // Used in kotlin-native @Suppress("unused") // Used in kotlin-native
fun <Context : CommonBackendContext, OldData, NewData> takeFromContext(op: (Context) -> NewData) = fun <Context : CommonBackendContext, OldData, NewData> takeFromContext(op: (Context) -> NewData): CompilerPhase<Context, OldData, NewData> =
object : CompilerPhase<Context, OldData, NewData> { object : CompilerPhase<Context, OldData, NewData> {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<OldData>, context: Context, input: OldData) = op(context) override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<OldData>, context: Context, input: OldData) = op(context)
} }
fun <Context : CommonBackendContext, OldData, NewData> transform(op: (OldData) -> NewData) = fun <Context : CommonBackendContext, OldData, NewData> transform(op: (OldData) -> NewData): CompilerPhase<Context, OldData, NewData> =
object : CompilerPhase<Context, OldData, NewData> { object : CompilerPhase<Context, OldData, NewData> {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<OldData>, context: Context, input: OldData) = op(input) override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<OldData>, context: Context, input: OldData) = op(input)
} }