-
Notifications
You must be signed in to change notification settings - Fork 139
Open
Description
Hello, when I try to translate operations with Polygeist that call virtual functions, I find that the base class calls the functions of the base class, not the functions overridden by the subclass. The sample I used is as follows. The comments are the translated result. The command I used is cgeist test.cpp --function=main --resource-dir=/Polygeist/llvm-project/build/lib/clang/18 -I /Polygeist/tools/cgeist/Test/polybench/utilities -S
In the base class, vfunc is an addition operation. In the subclass, it is rewritten as a subtraction operation. The final translation is the addition operation of the base class(%12 = arith.addi %10, %11 : i32
) instead of the expected subtraction operation of the subclass.
#include <new>
#include <cstdio>
class SimStream {
public:
int n;
SimStream() {
n = 0;
}
virtual int vfunc(int val1 , int val2) {
return val1 + val2;
}
};
class subSimStream : public SimStream {
public:
int vfunc(int val1 , int val2) override {
return val1 - val2;
}
};
int myfunc(SimStream *ptr , int val1 , int val2) {
int output = ptr->vfunc(val1 , val2);
return output;
}
int main() {
SimStream *r = new subSimStream;
int val1 , val2 , output;
scanf("%d%d" , &val1 , &val2);
output = r->vfunc(val1 , val2);
printf("output = %d\n" , output);
delete r;
return 0;
}
/*
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<i32, dense<32> : vector<2xi32>>, #dlti.dl_entry<f16, dense<16> : vector<2xi32>>, #dlti.dl_entry<f64, dense<64> : vector<2xi32>>, #dlti.dl_entry<i16, dense<16> : vector<2xi32>>, #dlti.dl_entry<f128, dense<128> : vector<2xi32>>, #dlti.dl_entry<i8, dense<8> : vector<2xi32>>, #dlti.dl_entry<i1, dense<8> : vector<2xi32>>, #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi32>>, #dlti.dl_entry<f80, dense<128> : vector<2xi32>>, #dlti.dl_entry<i64, dense<64> : vector<2xi32>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi32>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi32>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi32>>, #dlti.dl_entry<"dlti.stack_alignment", 128 : i32>, #dlti.dl_entry<"dlti.endianness", "little">>, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu", "polygeist.target-cpu" = "x86-64", "polygeist.target-features" = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87", "polygeist.tune-cpu" = "generic"} {
llvm.func @free(!llvm.ptr)
llvm.mlir.global internal constant @str1("output = %d\0A\00") {addr_space = 0 : i32}
llvm.func @printf(!llvm.ptr, ...) -> i32
llvm.mlir.global internal constant @str0("%d%d\00") {addr_space = 0 : i32}
llvm.func @scanf(!llvm.ptr, ...) -> i32
func.func @main() -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
%c0_i32 = arith.constant 0 : i32
%0 = llvm.mlir.undef : i32
%alloca = memref.alloca() : memref<1xi32>
affine.store %0, %alloca[0] : memref<1xi32>
%alloca_0 = memref.alloca() : memref<1xi32>
affine.store %0, %alloca_0[0] : memref<1xi32>
%alloc = memref.alloc() : memref<1x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>
%cast = memref.cast %alloc : memref<1x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>> to memref<?x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>
call @_ZN12subSimStreamC1Ev(%cast) : (memref<?x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>) -> ()
%1 = "polygeist.memref2pointer"(%alloc) : (memref<1x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>) -> !llvm.ptr
%2 = llvm.mlir.zero : !llvm.ptr
%3 = llvm.icmp "ne" %1, %2 : !llvm.ptr
%4 = arith.select %3, %1, %2 : !llvm.ptr
%5 = llvm.mlir.addressof @str0 : !llvm.ptr
%6 = llvm.getelementptr %5[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<5 x i8>
%7 = "polygeist.memref2pointer"(%alloca_0) : (memref<1xi32>) -> !llvm.ptr
%8 = "polygeist.memref2pointer"(%alloca) : (memref<1xi32>) -> !llvm.ptr
%9 = llvm.call @scanf(%6, %7, %8) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> i32
%10 = affine.load %alloca_0[0] : memref<1xi32>
%11 = affine.load %alloca[0] : memref<1xi32>
%12 = arith.addi %10, %11 : i32
%13 = llvm.mlir.addressof @str1 : !llvm.ptr
%14 = llvm.getelementptr %13[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<13 x i8>
%15 = llvm.call @printf(%14, %12) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i32) -> i32
llvm.call @free(%4) : (!llvm.ptr) -> ()
return %c0_i32 : i32
}
func.func @_ZN12subSimStreamC1Ev(%arg0: memref<?x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>) attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
%0 = "polygeist.memref2pointer"(%arg0) : (memref<?x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>) -> !llvm.ptr
%1 = "polygeist.pointer2memref"(%0) : (!llvm.ptr) -> memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>
call @_ZN9SimStreamC1Ev(%1) : (memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>) -> ()
return
}
func.func @_ZN9SimStream5vfuncEii(%arg0: memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>, %arg1: i32, %arg2: i32) -> i32 attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
%0 = arith.addi %arg1, %arg2 : i32
return %0 : i32
}
func.func @_ZN9SimStreamC1Ev(%arg0: memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>) attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
%c0_i32 = arith.constant 0 : i32
%0 = "polygeist.memref2pointer"(%arg0) : (memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>) -> !llvm.ptr
%1 = llvm.getelementptr %0[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<packed (ptr, i32, array<4 x i8>)>
llvm.store %c0_i32, %1 : i32, !llvm.ptr
return
}
}
*/
Metadata
Metadata
Assignees
Labels
No labels