Skip to content

Commit

Permalink
Lower upcast instructions to bitcast
Browse files Browse the repository at this point in the history
- upcast and bitcast instructions represent the same operation: an
  unchecked cast. The only difference is that upcasts are guaranteed
  to be safe by the type system.
- Lowered code can't really be considered type safe anymore because
  high level relations like subclasses are gone: we are just left with
  pointers to apparently unrelated structs. Upcasts between lowered
  types are no longer valid.
- This change converts all upcasts to bitcasts so lowered code is
  still valid.
  • Loading branch information
jayconrod committed Nov 19, 2011
1 parent 6dffe6d commit d9b2bdb
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
12 changes: 12 additions & 0 deletions core/src/main/scala/tungsten/LowerPass.scala
Expand Up @@ -339,6 +339,8 @@ class LowerInstructionsPass
convertPCallInstruction(pcallInst, module)
case scallInst: StaticCallInstruction =>
convertSCallInstruction(scallInst, module)
case upcastInst: UpcastInstruction =>
convertUpcastInstruction(upcastInst, module)
case vcallInst: VirtualCallInstruction =>
convertVCallInstruction(vcallInst, module)
case vlookupInst: VirtualLookupInstruction =>
Expand Down Expand Up @@ -477,6 +479,16 @@ class LowerInstructionsPass
RewrittenInstructions(argumentInsts ++ returnInsts)
}

def convertUpcastInstruction(upcastInst: UpcastInstruction,
module: Module): RewriteResult =
{
val bitcast = BitCastInstruction(upcastInst.name,
upcastInst.ty,
upcastInst.value,
upcastInst.annotations)
RewrittenInstructions(List(bitcast))
}

def convertVCallInstruction(vcallInst: VirtualCallInstruction,
module: Module): RewriteResult =
{
Expand Down
12 changes: 6 additions & 6 deletions core/src/test/scala/tungsten/LowerPassTest.scala
Expand Up @@ -376,7 +376,7 @@ class LowerPassInstructionConversionTest {
def testVCallInterface {
val code = "interface @I %i = upcast null\n" +
"unit %x = vcall interface @I %i:1()"
val expectedCode = "interface @I %i = upcast null\n" +
val expectedCode = "interface @I %i = bitcast null\n" +
"int8* %x.vtable$#1 = scall @tungsten.load_ivtable(interface @I %i, struct @tungsten.interface_info* @I.info$)\n" +
"struct @I.vtable_type$* %x.vtable$#2 = bitcast int8* %x.vtable$#1\n" +
"(interface @I)->unit %x.method$#3 = loadelement struct @I.vtable_type$* %x.vtable$#2, int64 0, int64 1\n" +
Expand All @@ -396,7 +396,7 @@ class LowerPassInstructionConversionTest {
def testVLookupInterface {
val code = "interface @I %i = upcast null\n" +
"(interface @I)->unit %m = vlookup interface @I %i:1"
val expectedCode = "interface @I %i = upcast null\n" +
val expectedCode = "interface @I %i = bitcast null\n" +
"int8* %m.vtable$#1 = scall @tungsten.load_ivtable(interface @I %i, struct @tungsten.interface_info* @I.info$)\n" +
"struct @I.vtable_type$* %m.vtable$#2 = bitcast int8* %m.vtable$#1\n" +
"(interface @I)->unit %m = loadelement struct @I.vtable_type$* %m.vtable$#2, int64 0, int64 1\n"
Expand All @@ -407,7 +407,7 @@ class LowerPassInstructionConversionTest {
def testPCallTypeParameters {
val code = "class @C %x = upcast null\n" +
"class @C %y = pcall [@g.T](type @g.T)->type @g.T @g[class @C](class @C %x)\n"
val expectedCode = "class @C %x = upcast null\n" +
val expectedCode = "class @C %x = bitcast null\n" +
"type @g.T %y.cast$#1 = bitcast class @C %x\n" +
"type @g.T %y.cast$#2 = pcall [@g.T](type @g.T)->type @g.T @g(type @g.T %y.cast$#1)\n" +
"class @C %y = bitcast type @g.T %y.cast$#2"
Expand All @@ -418,7 +418,7 @@ class LowerPassInstructionConversionTest {
def testSCallTypeParameters {
val code = "class @C %x = upcast null\n" +
"class @C %y = scall @g[class @C](class @C %x)\n"
val expectedCode = "class @C %x = upcast null\n" +
val expectedCode = "class @C %x = bitcast null\n" +
"type @g.T %y.cast$#1 = bitcast class @C %x\n" +
"type @g.T %y.cast$#2 = scall @g(type @g.T %y.cast$#1)\n" +
"class @C %y = bitcast type @g.T %y.cast$#2\n"
Expand All @@ -429,7 +429,7 @@ class LowerPassInstructionConversionTest {
def testVCallTypeParameters {
val code = "class @C %x = upcast null\n" +
"class @C %y = vcall class @C %x:2[class @C](class @C %x)\n"
val expectedCode = "class @C %x = upcast null\n" +
val expectedCode = "class @C %x = bitcast null\n" +
"struct @C.vtable_type$* %y.vtable$#1 = loadelement class @C %x, int64 0, int64 0\n" +
"[@C.id.T](class @C, type @C.id.T)->type @C.id.T %y.method$#2 = loadelement struct @C.vtable_type$* %y.vtable$#1, int64 0, int64 4\n" +
"type @C.id.T %y.cast$#3 = bitcast class @C %x\n" +
Expand Down Expand Up @@ -466,7 +466,7 @@ class LowerPassInstructionConversionTest {
" unit %anon$#1 = branch @f.bb(int64 12)\n" +
" }\n" +
" block %bb(int64 @f.bb.m) {\n" +
" struct @tungsten.Object.data$*? %a = upcast null\n" +
" struct @tungsten.Object.data$*? %a = bitcast null\n" +
" int64 %n = binop int64 %m + int64 %m\n" +
" struct @tungsten.Object.data$* %b = bitcast struct @tungsten.Object.data$*? %a\n" +
" boolean @f.bb.b.cmp$#16 = relop struct @tungsten.Object.data$*? %a == bitcast null to struct @tungsten.Object.data$*?\n" +
Expand Down

0 comments on commit d9b2bdb

Please sign in to comment.