Skip to content

Commit 7725312

Browse files
committed
WIP remove dead code in the optimizer
1 parent 7514721 commit 7725312

File tree

7 files changed

+49
-192
lines changed

7 files changed

+49
-192
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
295295

296296
val info = MethodInlineInfo(
297297
effectivelyFinal = effectivelyFinal,
298-
traitMethodWithStaticImplementation = false,
299298
annotatedInline = methodSym.hasAnnotation(ScalaInlineClass),
300299
annotatedNoInline = methodSym.hasAnnotation(ScalaNoInlineClass)
301300
)

src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -255,13 +255,11 @@ abstract class BTypes {
255255
val methodInfos = classNode.methods.asScala.map(methodNode => {
256256
val info = MethodInlineInfo(
257257
effectivelyFinal = BytecodeUtils.isFinalMethod(methodNode),
258-
traitMethodWithStaticImplementation = false,
259258
annotatedInline = false,
260259
annotatedNoInline = false)
261260
(methodNode.name + methodNode.desc, info)
262261
}).toMap
263262
InlineInfo(
264-
traitImplClassSelfType = None,
265263
isEffectivelyFinal = BytecodeUtils.isFinalClass(classNode),
266264
sam = inlinerHeuristics.javaSam(classNode.name),
267265
methodInfos = methodInfos,
@@ -1139,22 +1137,8 @@ object BTypes {
11391137
* Note that this class should contain information that can only be obtained from the ClassSymbol.
11401138
* Information that can be computed from the ClassNode should be added to the call graph instead.
11411139
*
1142-
* @param traitImplClassSelfType `Some(tp)` if this InlineInfo describes a trait, and the `self`
1143-
* parameter type of the methods in the implementation class is not
1144-
* the trait itself. Example:
1145-
* trait T { self: U => def f = 1 }
1146-
* Generates something like:
1147-
* class T$class { static def f(self: U) = 1 }
1148-
*
1149-
* In order to inline a trat method call, the INVOKEINTERFACE is
1150-
* rewritten to an INVOKESTATIC of the impl class, so we need the
1151-
* self type (U) to get the right signature.
1152-
*
1153-
* `None` if the self type is the interface type, or if this
1154-
* InlineInfo does not describe a trait.
1155-
*
11561140
* @param isEffectivelyFinal True if the class cannot have subclasses: final classes, module
1157-
* classes, trait impl classes.
1141+
* classes.
11581142
*
11591143
* @param sam If this class is a SAM type, the SAM's "$name$descriptor".
11601144
*
@@ -1166,26 +1150,21 @@ object BTypes {
11661150
* InlineInfo, for example if some classfile could not be found on
11671151
* the classpath. This warning can be reported later by the inliner.
11681152
*/
1169-
final case class InlineInfo(traitImplClassSelfType: Option[InternalName],
1170-
isEffectivelyFinal: Boolean,
1153+
final case class InlineInfo(isEffectivelyFinal: Boolean,
11711154
sam: Option[String],
11721155
methodInfos: Map[String, MethodInlineInfo],
11731156
warning: Option[ClassInlineInfoWarning])
11741157

1175-
val EmptyInlineInfo = InlineInfo(None, false, None, Map.empty, None)
1158+
val EmptyInlineInfo = InlineInfo(false, None, Map.empty, None)
11761159

11771160
/**
11781161
* Metadata about a method, used by the inliner.
11791162
*
11801163
* @param effectivelyFinal True if the method cannot be overridden (in Scala)
1181-
* @param traitMethodWithStaticImplementation True if the method is an interface method method of
1182-
* a trait method and has a static counterpart in the
1183-
* implementation class.
11841164
* @param annotatedInline True if the method is annotated `@inline`
11851165
* @param annotatedNoInline True if the method is annotated `@noinline`
11861166
*/
11871167
final case class MethodInlineInfo(effectivelyFinal: Boolean,
1188-
traitMethodWithStaticImplementation: Boolean,
11891168
annotatedInline: Boolean,
11901169
annotatedNoInline: Boolean)
11911170

src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -132,17 +132,9 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
132132
(declarationClassNode, source) <- byteCodeRepository.classNodeAndSource(declarationClass): Either[OptimizerWarning, (ClassNode, Source)]
133133
} yield {
134134
val declarationClassBType = classBTypeFromClassNode(declarationClassNode)
135-
val CallsiteInfo(safeToInline, safeToRewrite, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call.owner, source)
136-
Callee(
137-
callee = method,
138-
calleeDeclarationClass = declarationClassBType,
139-
safeToInline = safeToInline,
140-
safeToRewrite = false,
141-
canInlineFromSource = canInlineFromSource,
142-
annotatedInline = annotatedInline,
143-
annotatedNoInline = annotatedNoInline,
144-
samParamTypes = samParamTypes,
145-
calleeInfoWarning = warning)
135+
val info = analyzeCallsite(method, declarationClassBType, call.owner, source)
136+
import info._
137+
Callee(callee = method, calleeDeclarationClass = declarationClassBType, safeToInline = safeToInline, canInlineFromSource = canInlineFromSource, annotatedInline = annotatedInline, annotatedNoInline = annotatedNoInline, samParamTypes = samParamTypes, calleeInfoWarning = warning)
146138
}
147139

148140
val argInfos = computeArgInfos(callee, call, prodCons)
@@ -256,7 +248,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
256248
/**
257249
* Just a named tuple used as return type of `analyzeCallsite`.
258250
*/
259-
private case class CallsiteInfo(safeToInline: Boolean, safeToRewrite: Boolean, canInlineFromSource: Boolean,
251+
private case class CallsiteInfo(safeToInline: Boolean, canInlineFromSource: Boolean,
260252
annotatedInline: Boolean, annotatedNoInline: Boolean,
261253
samParamTypes: IntMap[ClassBType],
262254
warning: Option[CalleeInfoWarning])
@@ -299,16 +291,12 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
299291
receiverType.info.orThrow.inlineInfo.isEffectivelyFinal // (1)
300292
}
301293

302-
val isRewritableTraitCall = false
303-
304294
val warning = calleeDeclarationClassBType.info.orThrow.inlineInfo.warning.map(
305295
MethodInlineInfoIncomplete(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, _))
306296

307297
// (1) For invocations of final trait methods, the callee isStaticallyResolved but also
308298
// abstract. Such a callee is not safe to inline - it needs to be re-written to the
309299
// static impl method first (safeToRewrite).
310-
// (2) Final trait methods can be rewritten from the interface to the static implementation
311-
// method to enable inlining.
312300
CallsiteInfo(
313301
safeToInline =
314302
canInlineFromSource &&
@@ -317,7 +305,6 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
317305
!BytecodeUtils.isConstructor(calleeMethodNode) &&
318306
!BytecodeUtils.isNativeMethod(calleeMethodNode) &&
319307
!BytecodeUtils.hasCallerSensitiveAnnotation(calleeMethodNode),
320-
safeToRewrite = canInlineFromSource && isRewritableTraitCall, // (2)
321308
canInlineFromSource = canInlineFromSource,
322309
annotatedInline = methodInlineInfo.annotatedInline,
323310
annotatedNoInline = methodInlineInfo.annotatedNoInline,
@@ -326,12 +313,12 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
326313

327314
case None =>
328315
val warning = MethodInlineInfoMissing(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, calleeDeclarationClassBType.info.orThrow.inlineInfo.warning)
329-
CallsiteInfo(false, false, false, false, false, IntMap.empty, Some(warning))
316+
CallsiteInfo(false, false, false, false, IntMap.empty, Some(warning))
330317
}
331318
} catch {
332319
case Invalid(noInfo: NoClassBTypeInfo) =>
333320
val warning = MethodInlineInfoError(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, noInfo)
334-
CallsiteInfo(false, false, false, false, false, IntMap.empty, Some(warning))
321+
CallsiteInfo(false, false, false, false, IntMap.empty, Some(warning))
335322
}
336323
}
337324

@@ -386,20 +373,13 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
386373
* @param calleeDeclarationClass The class in which the callee is declared
387374
* @param safeToInline True if the callee can be safely inlined: it cannot be overridden,
388375
* and the inliner settings (project / global) allow inlining it.
389-
* @param safeToRewrite True if the callee is the interface method of a concrete trait method
390-
* that can be safely re-written to the static implementation method.
391376
* @param annotatedInline True if the callee is annotated @inline
392377
* @param annotatedNoInline True if the callee is annotated @noinline
393378
* @param samParamTypes A map from parameter positions to SAM parameter types
394379
* @param calleeInfoWarning An inliner warning if some information was not available while
395380
* gathering the information about this callee.
396381
*/
397-
final case class Callee(callee: MethodNode, calleeDeclarationClass: ClassBType,
398-
safeToInline: Boolean, safeToRewrite: Boolean, canInlineFromSource: Boolean,
399-
annotatedInline: Boolean, annotatedNoInline: Boolean,
400-
samParamTypes: IntMap[ClassBType],
401-
calleeInfoWarning: Option[CalleeInfoWarning]) {
402-
assert(!(safeToInline && safeToRewrite), s"A callee of ${callee.name} can be either safeToInline or safeToRewrite, but not both.")
382+
final case class Callee(callee: MethodNode, calleeDeclarationClass: btypes.ClassBType, safeToInline: Boolean, canInlineFromSource: Boolean, annotatedInline: Boolean, annotatedNoInline: Boolean, samParamTypes: IntMap[btypes.ClassBType], calleeInfoWarning: Option[CalleeInfoWarning]) {
403383
override def toString = s"Callee($calleeDeclarationClass.${callee.name})"
404384
}
405385

src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -359,16 +359,7 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) {
359359
case (bodyMethodNode, bodyMethodDeclClass) =>
360360
val bodyDeclClassType = classBTypeFromParsedClassfile(bodyMethodDeclClass)
361361
val canInlineFromSource = compilerSettings.YoptInlineGlobal || bodyMethodIsBeingCompiled
362-
Callee(
363-
callee = bodyMethodNode,
364-
calleeDeclarationClass = bodyDeclClassType,
365-
safeToInline = canInlineFromSource,
366-
safeToRewrite = false, // the lambda body method is not a trait interface method
367-
canInlineFromSource = canInlineFromSource,
368-
annotatedInline = false,
369-
annotatedNoInline = false,
370-
samParamTypes = callGraph.samParamTypes(bodyMethodNode, bodyDeclClassType),
371-
calleeInfoWarning = None)
362+
Callee(callee = bodyMethodNode, calleeDeclarationClass = bodyDeclClassType, safeToInline = canInlineFromSource, canInlineFromSource = canInlineFromSource, annotatedInline = false, annotatedNoInline = false, samParamTypes = callGraph.samParamTypes(bodyMethodNode, bodyDeclClassType), calleeInfoWarning = None)
372363
})
373364
val argInfos = closureInit.capturedArgInfos ++ originalCallsite.map(cs => cs.argInfos map {
374365
case (index, info) => (index + numCapturedValues, info)

src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import scala.tools.nsc.backend.jvm.BackendReporting.UnknownScalaInlineInfoVersio
2727
* In principle we could encode the InlineInfo into a Java annotation (instead of a classfile attribute).
2828
* However, an attribute allows us to save many bits. In particular, note that the strings in an
2929
* InlineInfo are serialized as references to constants in the constant pool, and those strings
30-
* (traitImplClassSelfType, method names, method signatures) would exist in there anyway. So the
30+
* (method names, method signatures) would exist in there anyway. So the
3131
* ScalaInlineAttribute remains relatively compact.
3232
*/
3333
case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineInfoAttribute.attributeName) {
@@ -49,14 +49,9 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI
4949

5050
var finalSelfSam = 0
5151
if (inlineInfo.isEffectivelyFinal) finalSelfSam |= 1
52-
if (inlineInfo.traitImplClassSelfType.isDefined) finalSelfSam |= 2
53-
if (inlineInfo.sam.isDefined) finalSelfSam |= 4
52+
if (inlineInfo.sam.isDefined) finalSelfSam |= 2
5453
result.putByte(finalSelfSam)
5554

56-
for (selfInternalName <- inlineInfo.traitImplClassSelfType) {
57-
result.putShort(cw.newUTF8(selfInternalName))
58-
}
59-
6055
for (samNameDesc <- inlineInfo.sam) {
6156
val (name, desc) = samNameDesc.span(_ != '(')
6257
result.putShort(cw.newUTF8(name))
@@ -76,9 +71,8 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI
7671

7772
var inlineInfo = 0
7873
if (info.effectivelyFinal) inlineInfo |= 1
79-
if (info.traitMethodWithStaticImplementation) inlineInfo |= 2
80-
if (info.annotatedInline) inlineInfo |= 4
81-
if (info.annotatedNoInline) inlineInfo |= 8
74+
if (info.annotatedInline) inlineInfo |= 2
75+
if (info.annotatedNoInline) inlineInfo |= 4
8276
result.putByte(inlineInfo)
8377
}
8478

@@ -103,7 +97,7 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI
10397
if (version == 1) {
10498
val finalSelfSam = nextByte()
10599
val isFinal = (finalSelfSam & 1) != 0
106-
val hasSelf = (finalSelfSam & 2) != 0
100+
val hasSelf = (finalSelfSam & 2) != 0 // no longer used
107101
val hasSam = (finalSelfSam & 4) != 0
108102

109103
val self = if (!hasSelf) None else {
@@ -124,13 +118,37 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI
124118

125119
val inlineInfo = nextByte()
126120
val isFinal = (inlineInfo & 1) != 0
127-
val traitMethodWithStaticImplementation = (inlineInfo & 2) != 0
121+
val traitMethodWithStaticImplementation = (inlineInfo & 2) != 0 // no longer used
128122
val isInline = (inlineInfo & 4) != 0
129123
val isNoInline = (inlineInfo & 8) != 0
130-
(name + desc, MethodInlineInfo(isFinal, traitMethodWithStaticImplementation, isInline, isNoInline))
124+
(name + desc, MethodInlineInfo(isFinal, isInline, isNoInline))
125+
}).toMap
126+
127+
InlineInfoAttribute(InlineInfo(isFinal, sam, infos, None))
128+
} else if (version == 2) {
129+
val finalSelfSam = nextByte()
130+
val isFinal = (finalSelfSam & 1) != 0
131+
val hasSam = (finalSelfSam & 2) != 0
132+
133+
val sam = if (!hasSam) None else {
134+
val name = nextUTF8()
135+
val desc = nextUTF8()
136+
Some(name + desc)
137+
}
138+
139+
val numEntries = nextShort()
140+
val infos = (0 until numEntries).map(_ => {
141+
val name = nextUTF8()
142+
val desc = nextUTF8()
143+
144+
val inlineInfo = nextByte()
145+
val isFinal = (inlineInfo & 1) != 0
146+
val isInline = (inlineInfo & 2) != 0
147+
val isNoInline = (inlineInfo & 4) != 0
148+
(name + desc, MethodInlineInfo(isFinal, isInline, isNoInline))
131149
}).toMap
132150

133-
InlineInfoAttribute(InlineInfo(self, isFinal, sam, infos, None))
151+
InlineInfoAttribute(InlineInfo(isFinal, sam, infos, None))
134152
} else {
135153
val msg = UnknownScalaInlineInfoVersion(cr.getClassName, version)
136154
InlineInfoAttribute(BTypes.EmptyInlineInfo.copy(warning = Some(msg)))
@@ -141,16 +159,15 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI
141159
object InlineInfoAttribute {
142160
/**
143161
* [u1] version
144-
* [u1] isEffectivelyFinal (<< 0), hasTraitImplClassSelfType (<< 1), hasSam (<< 2)
145-
* [u2]? traitImplClassSelfType (reference)
162+
* [u1] isEffectivelyFinal (<< 0), hasSam (<< 1)
146163
* [u2]? samName (reference)
147164
* [u2]? samDescriptor (reference)
148165
* [u2] numMethodEntries
149166
* [u2] name (reference)
150167
* [u2] descriptor (reference)
151-
* [u1] isFinal (<< 0), traitMethodWithStaticImplementation (<< 1), hasInlineAnnotation (<< 2), hasNoInlineAnnotation (<< 3)
168+
* [u1] isFinal (<< 0), hasInlineAnnotation (<< 2), hasNoInlineAnnotation (<< 3)
152169
*/
153-
final val VERSION: Byte = 1
170+
final val VERSION: Byte = 2
154171

155172
final val attributeName = "ScalaInlineInfo"
156173
}
@@ -159,4 +176,4 @@ object InlineInfoAttribute {
159176
* In order to instruct the ASM framework to de-serialize the ScalaInlineInfo attribute, we need
160177
* to pass a prototype instance when running the class reader.
161178
*/
162-
object InlineInfoAttributePrototype extends InlineInfoAttribute(InlineInfo(null, false, null, null, null))
179+
object InlineInfoAttributePrototype extends InlineInfoAttribute(InlineInfo(false, null, null, null))

0 commit comments

Comments
 (0)