[vm/compiler] Partially revert "Replace LoadClassId for known cids."

We still need to check for concrete types in
ConstantPropagator::VisitLoadClassId to avoid benchmark regressions.

Change-Id: Ie3a7e3aaa3b261c34760308f3cb1d328ce2d8493
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103520
Commit-Queue: Teagan Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 44a3055..dc78a0e 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -856,9 +856,23 @@
 }
 
 void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) {
+  // This first part duplicates the work done in LoadClassIdInstr::Canonicalize,
+  // which replaces uses of LoadClassIdInstr where the object has a concrete
+  // type with a Constant. Canonicalize runs before the ConstantPropagation
+  // pass, so if that was all, this wouldn't be needed.
+  //
+  // However, the ConstantPropagator also runs as part of OptimizeBranches, and
+  // TypePropagation runs between it and the previous Canonicalize. Thus, the
+  // type may have become concrete and we should take that into account. Not
+  // doing so led to some benchmark regressions.
+  intptr_t cid = instr->object()->Type()->ToCid();
+  if (cid != kDynamicCid) {
+    SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid)));
+    return;
+  }
   const Object& object = instr->object()->definition()->constant_value();
   if (IsConstant(object)) {
-    const intptr_t cid = object.GetClassId();
+    cid = object.GetClassId();
     SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid)));
     return;
   }