我的目标是获取不同语言(主要是 C、C++、Obj-C 和 Haskell)的源代码,并提供有关它们的各种统计信息。 (例如变量、函数、内存分配、复杂性等的数量)
LLVM 似乎是一个完美的工具,因为我可以为这些语言生成位码,并且通过 LLVM 的可定制通道,我几乎可以做任何事情。对于 C 系列它工作得很好,采取一个 C 程序(test.c
) 例如:
#include <stdio.h>
int main( )
{
int num1, num2, sum;
printf("Enter two integers: ");
scanf("%d %d", &num1, &num2);
sum = num1 + num2;
printf("Sum: %d",sum);
return 0;
}
然后我运行:
clang -emit-llvm test.c -c -o test.bc
opt -load [MY AWESOME PASS] [ARGS]
瞧,我几乎拥有了我需要的一切:
1 instcount - Number of Add insts
4 instcount - Number of Alloca insts
3 instcount - Number of Call insts
3 instcount - Number of Load insts
1 instcount - Number of Ret insts
2 instcount - Number of Store insts
1 instcount - Number of basic blocks
14 instcount - Number of instructions (of all types)
12 instcount - Number of memory instructions
1 instcount - Number of non-external functions
我想通过 Haskell 程序实现同样的目标。拿test.hs
:
module Test where
quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
然而当我这样做时
ghc -fllvm -keep-llvm-files -fforce-recomp test.hs
opt -load [MY AWESOME PASS] [ARGS]
我得到以下结果,这对于我的目的来说似乎完全没有用(在本文开头提到),因为它们显然对于这几行代码来说是不正确的。我猜这与GHC有关,因为新创建的.ll
文件本身是 52Kb,而.ll
C程序文件只有2Kb。
31 instcount - Number of Add insts
92 instcount - Number of Alloca insts
2 instcount - Number of And insts
30 instcount - Number of BitCast insts
24 instcount - Number of Br insts
22 instcount - Number of Call insts
109 instcount - Number of GetElementPtr insts
17 instcount - Number of ICmp insts
54 instcount - Number of IntToPtr insts
326 instcount - Number of Load insts
65 instcount - Number of PtrToInt insts
22 instcount - Number of Ret insts
206 instcount - Number of Store insts
8 instcount - Number of Sub insts
46 instcount - Number of basic blocks
1008 instcount - Number of instructions (of all types)
755 instcount - Number of memory instructions
10 instcount - Number of non-external functions
我的问题是,在没有这些巨大数字的情况下,我应该如何继续能够将 Haskell 代码与其他代码进行比较?有可能吗?我应该继续使用 GHC 生成 LLVM IR 吗?我还应该使用哪些其他工具?