Peng Yu via llvm-dev
2019-Jan-18 16:57 UTC
[llvm-dev] Why hasExternalLinkage() is not true for an external variable?
Hi, I am trying to test whether an operand is external or not (code is shown below). The variable "U" should be a global variable. But hasExternalLinkage() returns 0 for it. Why is it so? How to only keep global variables (note that global functions are also shown)? Thanks $ clang++ -std=c++11 -fno-rtti -Wall -pedantic -I$HOME/llvm/include -fPIC -c -o fun2var.o fun2var.cpp $ clang fun2var.o '-Wl,-flat_namespace' '-Wl,-undefined' '-Wl,suppress' -shared -o ./libfun2var.so $ opt -load libfun2var.so -fun2var < hello.exe.0.0.preopt.bc 2>&1 1>/dev/null main u 1 0 main u 1 0 main f 0 1 f llvm.dbg.declare 0 1 f U 0 0 f U 0 0 f u.3 1 0 f u.3 1 0 ==> fun2var.cpp <=/* vim: set noexpandtab tabstop=2: */ #include "llvm/ADT/Statistic.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/InstIterator.h" #include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" #include <llvm/IR/DebugLoc.h> #include <llvm/IR/DebugInfoMetadata.h> using namespace llvm; namespace { // fun2var - The first implementation, without getAnalysisUsage. struct fun2var : public FunctionPass { static char ID; // Pass identification, replacement for typeid fun2var() : FunctionPass(ID) {} bool runOnFunction(Function &F) override { for (Instruction &I: instructions(F)) { for (Use &U: I.operands()) { if(isa<GlobalValue>(U)) { auto GV = dyn_cast<GlobalValue>(U); errs() << F.getName() << '\t' << U->getName() << '\t' << GV->hasInternalLinkage() << '\t' << GV->hasExternalLinkage() << "\n"; } } } return false; } }; } char fun2var::ID = 0; static RegisterPass<fun2var> X("fun2var", "fun2var Pass"); $ clang -g -flto -std=gnu99 -Wall -pedantic -c -o hello.o hello.c $ clang -g -flto -std=gnu99 -Wall -pedantic -c -o f.o f.c $ clang hello.o f.o -flto -fuse-ld=gold '-Wl,-plugin-opt=save-temps' -o hello.exe ==> f.c <=/* vim: set noexpandtab tabstop=2: */ #include <stdio.h> int U; static int u; void f(int i) { U+=i; u+=i; } ==> hello.c <=/* vim: set noexpandtab tabstop=2: */ #include <stdio.h> extern int U; static int u; void f(int i); int main() { ++u; f(10); return 0; } -- Regards, Peng
Eli Friedman via llvm-dev
2019-Jan-18 19:16 UTC
[llvm-dev] Why hasExternalLinkage() is not true for an external variable?
On 1/18/2019 8:57 AM, Peng Yu via llvm-dev wrote:> Hi, > > I am trying to test whether an operand is external or not (code is > shown below). The variable "U" should be a global variable. But > hasExternalLinkage() returns 0 for it. Why is it so?You probably want "!hasLocalLinkage()", or something like that. hasExternalLinkage() specifically checks for "external" linkage, but your variable has "common" linkage. See http://llvm.org/docs/LangRef.html#linkage-types . -Eli -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project