LINUX.ORG.RU

Проблемы с переопределением функций в llvm

 ,


0

1

Экспериментирую с LLVM, за основу взял калейдоскоп и слегка переделал его.
Было:

if (F->getName() != Name) {
    // Delete the one we just made and get the existing one.
    F->eraseFromParent();
    F = TheModule->getFunction(Name);
    
    // If F already has a body, reject this.
    if (!F->empty()) {
      ErrorF("redefinition of function");
      return 0;
    }
    
    // If F took a different number of args, reject.
    if (F->arg_size() != Args.size()) {
      ErrorF("redefinition of function with different # args");
      return 0;
    }
  }
Стало:
if (F->getName() != Name) {
    // Delete the one we just made and get the existing one.
    TheModule->getFunction(Name)->eraseFromParent();
    F->setName(Name);
  }

Проблема вот в чем:
Если объявить функцию def test(x) x+1;
Получим такое промежуточное представление:

define double @test(double %x) {
entry:
  %addtmp = fadd double 1.000000e+00, %x
  ret double %addtmp
}
И объявить функцию def test2(x) x+ test(x)
с промежуточным представлением
define double @test2(double %x) {
entry:
  %calltmp = call double @test(double %x)
  %addtmp = fadd double %x, %calltmp
  ret double %addtmp
}

Теперь если переопределить функцию def test(x) x
промежуточное представление которой

define double @test(double %x) {
entry:
  ret double %x
}

То попытка выполнить test2(1) (которое по идеи должно вернуть 2, а до переопределения - 3)
приведет к "Ошибка сегментирования"

Куда копать?
Хочу организовать переопределение как в python и sbcl.

★★★★★

Последнее исправление: deterok (всего исправлений: 2)

Кстати вот как выглядит работа сборшика:

rlwrap ./toy
ready> def test(x) x+1;
ready> Read function definition:
define double @test(double %x) {
entry:
  %addtmp = fadd double 1.000000e+00, %x
  ret double %addtmp
}

ready> def test2(x) x+test(x);
ready> Read function definition:
define double @test2(double %x) {
entry:
  %calltmp = call double @test(double %x)
  %addtmp = fadd double %x, %calltmp
  ret double %addtmp
}

ready> def test(x) x;
ready> Read function definition:
define double @test(double %x) {
entry:
  ret double %x
}

ready> test2(1);
ready> Stack dump:
0.      Running pass 'X86 DAG->DAG Instruction Selection' on function '@test2'
rlwrap: warning: toy killed by SIGSEGV.
rlwrap has not crashed, but for transparency,
it will now kill itself (without dumping core)with the same signal

Ошибка сегментирования

Пойду гуглить Running pass 'X86 DAG->DAG Instruction Selection' on function '@test2'

deterok ★★★★★
() автор топика

Не надо переопределять функции. Давай им новые имена и храни таблицу переименований.

anonymous
()
Ответ на: комментарий от anonymous

Т.е. мне надо создать массив пар с именами функций за которыми будут скрываться их списки переопределений,
а на место вызова функции ставить специальную функцию, которая будет искать нужную нам функцию в созданном массиве и брать ее последнюю реализации?
Тут возникает вопрос, а как такое решение скажется на производительности?

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

как такое решение скажется на производительности

Также как слово virtual в описании C++ класса.

monk ★★★★★
()
Ответ на: комментарий от deterok

Ты что курил и где ты это брал?

Таблицу переименований ты должен держать на этапе компиляции, а в рантайме у тебя тупо будут ссылки на функции foobar1, foobar2, foobar3 и так далее на каждое переопределение foobar.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.