是否有可能从子代中获得父代线程ID?
我正在尝试将仪器添加到我的代码中,以打印出 之类的东西 '线程1叉线2' 关于我如何实现这一目标的任何建议? 解决方案 术语校正:一个线程可能 create 另一个线程,而不是 fork ,通常是 用于提及一个过程. 否,线程无法获取另一线程的标识符.在Linux上,您可以检查gettid() == getpid()是否以查找是否是主线程. Solaris具有 thr_main()呼叫者是否是主线程. freebsd具有但是没有办法识别任何线程之间的亲子关系.任何线程都可以创建更多线程.在创建线程或使用全局数据结构时,您必须使用通过线程标识符来维护此信息.
14 2024-04-10
编程技术问答社区
计算数组的数量
如何在C程序中计数数组的总数? LLVM IR中的数组声明对应于Alloca的操作类型. 所以 int a[10]; 对应于 %a = alloca [10 x i32], align 4 在llvm ir中. ,但我也注意到 int j = 0; 也对应于Alloca指令 %j = alloca i32, align 4 那么如何计算仅与数组相对应的同种指令的数量? 编辑: for (Function::iterator i = F.begin(), e = F.end(); i != e; ++i) { for (BasicBlock::iterator ii =(*i).begin(), ii_e = (*i).end(); ii != ii_e; ++ii) { Instruction *n = dyn_cast(&*ii);
14 2024-04-10
编程技术问答社区
如何用clang和llvm-link链接一个库
我像这样编译了我的程序, clang++ -O4 -emit-llvm file1.cpp -c -o file1.bc -pthread clang++ -O4 -emit-llvm file2.cpp -c -o file2.bc -pthread llvm-link file1.bc file2.bc -o main.ll -S 我如何指定与 -ldl 链接 解决方案 llvm-link是一个程序,将llvm ir文件"链接"到一个IR文件中;您可以阅读有关它的更多信息如果您确实要生成对象代码和/或可执行文件,请参见以下问题: 如何使用LLVM生成机器代码 带外部库的llvm-link 简而言之,您应该使用本机工具来组装和链接(例如as和ld),尽管目前有一些实验支持用于生成对象文件以及在LLVM中链接. . 在任何情况下,Clang本身都可以调用平台链接器 - 实际上是默认值,但是当然,您已经通过提供-c>. 来覆盖.
18 2024-04-10
编程技术问答社区
如何用clang和llvm链接一个库|链接
我像这样编译了我的程序, clang++ -O4 -emit-llvm file1.cpp -c -o file1.bc -pthread clang++ -O4 -emit-llvm file2.cpp -c -o file2.bc -pthread llvm-link file1.bc file2.bc -o main.ll -S 我如何指定与 -ldl 链接 解决方案 llvm-link是一个程序,将llvm ir文件"链接"到一个IR文件中;您可以阅读有关它的更多信息如果您确实要生成对象代码和/或可执行文件,请参见以下问题: 如何使用LLVM生成机器代码 带外部库的llvm-link 简而言之,您应该使用本机工具来组装和链接(例如as和ld),尽管目前有一些实验支持用于生成对象文件以及在LLVM中链接. . 在任何情况下,Clang本身都可以调用平台链接器 - 实际上是默认值,但是当然,您已经通过提供-c>. 来覆盖.
12 2024-04-09
编程技术问答社区
在LLVM中为一个变量使用一个特定的寄存器
我正在编写修改LLVM比特码的LLVM通行证.对于一个变量,我希望它使用寄存器,例如x86上的R15.生成机器代码时,如何指示LLVM使用此寄存器?可以在比特级级别指示吗? 解决方案 您可以使用内联汇编器对此要求进行建模.没有办法"绑定"特定变量进行注册.
10 2024-04-09
编程技术问答社区
如何从Clang的Expr对象中获得Stmt类对象
我正在编写一个clang插件,以插入C代码中的断言.我已经实施了一个用于访问每个单一操作员的课程,并检查它是否是指针取消.如果是这样,我想插入一个无效的指针主张检查.但是我被卡住了,因为我无法弄清楚如何获取包含expr对象的clang中的STMT对象. 这是我的代码,它可以说明断言,但位于完全错误的位置(即指针退出后.我想在包含解雇的语句之前这样做. bool MyRecursiveASTVisitor::VisitUnaryOperator(UnaryOperator *E){ if (E->getOpcode() == UO_Deref ){ Expr *e1 = E->getSubExpr(); SourceLocation SL = E->getLocEnd(); Rewrite.InsertText(SL, "assert(", true, true); Rewrite.InsertText(S
12 2024-04-09
编程技术问答社区
有什么方法可以获得llvm deference指针值的原始类型(即指针类型)吗?
也许标题以某种方式感到困惑.但是让我举一个例子. void foo(int val) { // do something } int i = 27; int* pi = &i; foo(*pi); 在这里,如果我们使用clang对其进行编译,则 *pi的类型为i32,但我们知道PI是指针类型. 我的问题是我们使用函数:: getGetFunctionParamType方法,结果将是i32.但是,如何使用某种方法来获取" Pi"类型,而不是" *pi"类型?这个问题使我几天感到困惑. 更新: 我看到有人混淆了这个问题.好吧,我已经将此源代码编译到LLVM中间格式FLIE(即.因此(现在没有int,int*).而且我不想构造一种指针类型,我只想以某种方式将"反向" *pi"反向" *pi,以便我可以检查" pi"是指指针类型.情况就是这样:我有 *pi,在.ll文件中,也许Pi是 %pi = alloca i32*, align 32 %1 =
10 2024-04-09
编程技术问答社区
LLVM和GCC,不同的输出相同的代码
这是一个示例代码,只是为了显示与LLVM编译器和GCC的不同输出.我想知道为什么?答案应该非常简单,但我看不到. (xcode 4.6.1) 代码: #include #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) int increment() { static int i = 42; i += 5; printf("increment returns %d\n",i); return i; } int main( int argc, char ** argv ) { int x = 50; printf("max of %d and %d is %d\n", x,increment(),MAX(x, increment())); printf("max of %d and %d is %d\n", x,increment(),MAX(x, increme
18 2024-04-09
编程技术问答社区
用Clang编译DLL时指定DEF文件
我正在尝试使用Windows中的clang编译DLL clang -shared structs.c -o structs.dll 但是符号没有被导出.. 如果我将__declspec(dllexport)添加到我的structs.h中的声明中. 但是,我想使用我创建的DEF文件(structs.def)来执行此操作,但是我找不到如何将DEF文件传递给Clang. 任何帮助都会得到证明:/ 解决方案 最终发现了它 - 我们可以在clang中使用-wl标志将一些逗号分隔的参数传递给链接器. 可以使用/def参数指定DEF文件 示例 clang -shared structs.c -o structs.dll -Wl"/DEF:structs.def"
20 2024-04-09
编程技术问答社区
Clang集成汇编器和否定过程中的 "表达式中的未知标记 "问题
我们在默认配置中使用clang.在默认配置中,使用Clang的集成汇编程序(而不是系统汇编器,例如GAS).我在确定确切的问题(和解决)方面遇到困难: make ... clang++ -DNDEBUG -g2 -O3 -Wall -fPIC -arch i386 -arch x86_64 -pipe -Wno-tautological-compare -c integer.cpp integer.cpp:542:2: error: unknown token in expression AS1( neg %1) ^ ./cpu.h:220:17: note: expanded from macro 'AS1' #define AS1(x) GNU_AS1(x) ^ ./cpu.h:215:24: note: expanded from macro 'GNU_
6 2024-04-09
编程技术问答社区
LLVM-GCC ASM到XCode中的LLVM
我得到了以下两个定义,使用Xcode LLVM-GCC编译器可以编译(和工作): #define SAVE_STACK(v)__asm { mov v, ESP } #define RESTORE_STACK __asm {sub ESP, s } 但是,当我将编译器更改为Apple LLVM时,我会收到以下错误: Expected '(' after 'asm' 我将{}替换为(),但这并不是一个问题,我在该错误上搜索了任何有用的东西...有人吗? 解决方案 __asm {...}内联装配的样式是非标准的,不受clang的支持.相反,C ++将Inline Assembly语法指定为asm("..."),请注意引号. clang也使用AT&T组装语法,因此需要重写宏以安全. 但是,一些工作一直在进行改善对微软非标准装配语法以及Intel样式组件的支持.有一个选项-fenable-experimental-ms-inline-asm可以启用到目前为止所做
16 2024-04-09
编程技术问答社区
LoadInst和StoreInst值和地址 LLVM
我有一个文件print.c,它具有两个函数: void printLoad(...) { // print address and value of memory location from which value printf("address=... value=...", ...); } void printStore(...) { // print address and value of memory location from which value } 我有一个LLVM通行证,该通行证在指令上迭代并添加CallInst指令trintload或printStore(取决于指令类型)(在当前的一项)之后(Load/store Inst). 为了调用此printStore或printload,我需要将适当的参数添加到CallInst :: Create函数,这是内存位置的地址和值. 这是我想实现的示例: define void @ma
10 2024-04-08
编程技术问答社区
在LLVM的两个块之间插入一个块
我想在LLVM中的两个基本块之间插入一个块.因此,例如,如果一个基本块A跳到基本块B,我想在它们之间插入基本的块C,以便跳到C和C跳到B.我该怎么做?我确实有一个基本思想,我需要更改基本块A的终止指令,以使目标b被C替换,但是我该如何继续在之间添加新的基本块C? 解决方案 是的,您需要更改(或替换)基本块A的终止指令 - 例如,如果是分支,则可以使用BranchInst::setSuccessor().然后,您可以创建基本的块C,并确保其终止指令跳到B,这将使其在中间. 您需要做的就是更改终结者的目标 - 您无需重新安排内存中的块顺序或类似的内容. 但是,您必须意识到,您需要担心两个特殊说明 - Phi节点和着陆垫. phi节点仅参考块的直接前任.这意味着,如果您在A和B之间插入C,则必须通过将它们删除或使其引用C而不是A. 来修复B中的所有PHI节点. 如果b是登陆板块(包含着陆板指示),则直接从调用指令的不愿意目标中跳入它才是合法的.如果从A到B的跳
8 2024-04-08
编程技术问答社区
Clang,微软链接器和标准库
我已经成功地使用了Microsoft C ++建造了Clang,我正在尝试将其编译为Hello World Test案例;它甚至可以生成一个对象文件,与标准库链接为剩余的绊脚石: hello-202520.o : error LNK2019: unresolved external symbol _printf referenced in function _main LINK : error LNK2001: unresolved external symbol _mainCRTStartup 往年有评论说clang尚未链接到Windows,但是我得到了这些链接,但实际上它确实能够生成Windows Format Object Files: clang -c hello.c ren hello.o hello.obj link hello.obj ...没有barf,因此文件格式似乎是正确的,但仍会遇到未解决的外部符号错误.可能会猜测Microsoft编译器标记其输
12 2024-04-08
编程技术问答社区
用LLVM通过参数传递结构
可以通过参数传递结构? 它与C ABI兼容? [edit] 基本上,我想拥有一个包含两个成员的C ++ POD(结构将是一个胖指针,带有指针和整数),并且能够将此结构作为函数参数传递在呼叫指令中(即使调用C代码). 我现在不使用Fat Pointer(指针和整数都在不同的函数参数中),我想知道在开始非常大的重构之前是否有可能! 解决方案 您可以做到这一点. 您可以通过将C代码复制并粘贴到LLVM的在线演示中, http://llvm.org/demo/index.cgi . 如果您在codepad.org上复制并粘贴代码,您会发现LLVM为myFunction生成以下内容: define void @_Z10myFunction10MyStruct_t(i8* %myStructAsParam.coerce0, i32 %myStructAsParam.coerce1) nounwind uwtable { %1 = tail
8 2024-04-08
编程技术问答社区
如何通过llvm | c api创建命名元数据?
我想将调试元数据添加到通过C API创建的生成的LLVM IR中.但是,我不知道如何创建命名元数据节点(例如!llvm.dbg.cu),甚至如何创建具有唯一数字的元数据节点(即!0,!1等).在说明中添加元数据操作数看起来很简单,但是我不知道如何创建独立的元数据节点. 解决方案 AS在LLVM 3.0处,C API中没有用于创建或修改命名元数据的函数.一个新功能(llvmaddnamedmetadataperand)是在3.0版本后,到API . 如果您可以从源头构建LLVM,则可以从树干中获得此支持.请参阅入门有关如何构建LLVM的页面.否则,您必须等到LLVM 3.1发布. 当功能可用时,这将是一个简单的调用问题: LLVMAddNamedMetadataOperand(module, "named_md_name", mdnode); 如果没有名称为"名称_md_name"的命名元数据,则将创建一个.否则将更新现有对象.
16 2024-04-08
编程技术问答社区
Clang是否为WebAssembly'的memory.fill和memory.copy提供本征?
我正在努力开发C中的WebAssembly模块,并一直在尝试使用memory.fill和memory.copy I know that Clang (v11.1.0) already 支持其他与内存有关的wasm intinsics 喜欢__builtin_wasm_memory_size和__builtin_wasm_memory_grow,但是如果它支持memory.fill和memory.copy>>>>>>>>>>>>>>>>>>>>>>>>>. 我对Clang/LLVM的内部工作并不十分熟悉,但是在几个地方暗示了这些说明的引用 [1] [2] (除非我误解了某些东西). 我尝试使用__builtin_memcpy和__builtin_memset: __attribute__((export_name("memcpy"))) void memcpy_test(void* mem_dst, void* mem_src) { __builtin_memcp
10 2024-04-08
编程技术问答社区
当从LLVM比特码编译对象时,不能针对静态库进行链接。
我正在开发LLVM编译器通行证.我通过以下方式运行通行证: 编译到LLVM BitCode clang foo.c -emit-llvm -c -o foo.bc 通过opt运行foo.bc(在没有此步骤的情况下仍然发生错误) 编译回对象文件 clang -c -o foo.o foo.bc 现在foo.o可能是静态库的一部分. ar rc libfoo.a foo.o 我无法与libfoo.a链接时,当我的所有C文件都以这种方式编译时. clang libfoo.a linkme.o -o linkme linkme.o:linkme.bc:function main: error: undefined reference to 'foo' clang: error: linker command failed with exit code 1 (use -v to see invocation) 源文件: foo.c:
16 2024-04-08
编程技术问答社区
LLVM的cpp后端,是否可以取代c后端?
我的问题是关于CPP后端,它的目的与C后端相同吗? C后端是我最喜欢的LLVM功能之一,我很沮丧. 真正的区别是什么? 我最感谢任何帮助. 参考: llvm 3.1发行注释 " C后端已被删除..." 解决方案 CPP后端创建LLVM API调用,以创建代表LLVM组件等效的AST.您可以在 http://llvm.org/demo/上尝试使用CPP后端.代码" target . C后端创建C代码,以执行LLVM组件的语义. 它们从根本上有所不同.
10 2024-04-08
编程技术问答社区
获取LLVM getelementptr中的操作数名称。
我正在尝试获取getElementPtr指令正在引用的数组的名称.当数组被索引使用实际C代码中的中间变量时,这似乎可以工作. int a = 0; i[a] = 3; 在这种情况下,我得到以下比特代码 %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* @i, i64 0, i64 %idxprom store i32 3, i32* %arrayidx, align 4 在这种情况下,我可以迭代GetElementPTR指令的操作数 并通过第一个操作数上的getName()方法找到数组(i)的名称. 但是,如果在源中,数组是直接的索引, i[0] = 3; 然后,生成的比特代码如下 store i32 3, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @i, i64 0, i64 0), align 4 在这里,我不确定
10 2024-04-08
编程技术问答社区