How do I run a non-legacy PassManager? I have tried doing the following but there is some exception thrown when trying to invalidate the analysis manager in the run function. Is there something else I should do for initialization?
llvm::AnalysisManager<Module> mm;
PassBuilder builder;
auto pm = builder.buildModuleOptimizationPipeline(PassBuilder::OptimizationLevel::O3);
pm.run(module, mm );
These snippets illustrate how to run and setup to run modern custom function and module pass on some .c/.cpp file... complete with a makefile. This works for LLVM 6 which is pretty recent (march 2018). It does not use the legacy pass manager.
HelloWorld.cpp:
#include <llvm/Pass.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/raw_ostream.h>
namespace {
struct Hello : public llvm::FunctionPass {
static char ID;
Hello() : llvm::FunctionPass{ID} {}
bool runOnFunction(llvm::Function &F) override {
llvm::errs() << "Hello ";
llvm::errs().write_escaped(F.getName()) << "\n";
return false;
}
};
struct Hello2 : public llvm::ModulePass {
static char ID;
Hello2() : llvm::ModulePass{ID} {}
bool runOnModule(llvm::Module &M) override {
llvm::errs() << "Name of the module ", llvm::errs().write_escaped(M.getName()) << "\n";
for(auto iter = M.getFunctionList().begin(); iter != M.getFunctionList().end(); ++iter) {
llvm::errs() << "Function name:" << iter->getName() << "\n";
}
return false;
}
};
}
char Hello::ID = 0;
static llvm::RegisterPass<Hello> X("Hello",
"Hello World Pass",
false,
false
);
char Hello2::ID = 1;
static llvm::RegisterPass<Hello2> Y("Hello2",
"Hello World2 pass",
false,
false
);
Corresponding makefile:
LLVM_VERSION=
LLVM_INCLUDEDIR = `llvm-config-6.0 --includedir`
LLVM_FLAGS = `llvm-config-6.0 --cxxflags --ldflags --system-libs --libs all`
CXX = clang++-6.0
CXXFLAGS = -g -std=c++11 -O3 -I $(LLVM_INCLUDEDIR) -I $(LLVM_INCLUDEDIR)
Hello.so:
$(CXX) -fPIC $(CXXFLAGS) HelloWorld.cpp $(LLVM_FLAGS) -shared -o Hello.so
Hello: Hello.so
testfile:
clang++-6.0 -emit-llvm -c test.cpp -o test.bc
runFunctionPassOnTestFile: Hello testfile
opt-6.0 -load ./Hello.so -Hello < test.bc > /dev/null
runModulePassOnTestfile: Hello testfile
opt-6.0 -load ./Hello.so -Hello2 < test.bc > /dev/null
clean:
rm *.o *.so *.out *~
DBG:
#echo LLVM INCLUDE DIRS $(LLVM_INCLUDEDIR) $(test)
A simple file to test everything on, test.cpp:
#include <stdio.h>
#include <stdlib.h>
int a = 4;
int c = 5;
int d = 6;
int e = 7;
int bar() { int *a = (int*) malloc(4); e = 1; return 1;}
int foo() { return 2; }
int barfoo() { return 3; }
int main() {
printf("Testing testing\n");
return 0;
}
Related
I figured that the problem was that I was not using ./a.out instead of ./filename, but that wasn't the case.
This is how I compile my program:
g++ -o -Wall -pthread filename.cpp
Running:
./filename
I figured that running pthread programs would be different than running a standard c++ program, but that wasn't the case.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct argStruct {
int arg1;
int arg2;
};
void *sum(void *arguments) {
struct argStruct *args = (struct argStruct *)arguments;
int a = args -> arg1;
int b = args -> arg2;
int c = a + b;
printf("%d + %d = %d ",a,b,c);
pthread_exit(NULL);
}
int main() {
pthread_t thr1, thr2;
struct argStruct args;
args.arg1 = 3;
args.arg2 = 10;
int t1, t2;
pthread_create(&thr1, NULL, &sum, (void *)&args);
pthread_create(&thr2, NULL, &sum, (void *)&args);
pthread_join(thr1, NULL);
pthread_join(thr2, NULL);
exit(EXIT_SUCCESS);
}
By calling
g++ -o -Wall -pthread filename.cpp
You instruct the compiler to write the result to a file named -Wall.
You therefore want to use one of these
g++ -Wall -pthread filename.cpp
g++ -Wall -pthread -o filename filename.cpp
The first writes the result to a.out, the second to filename. (Also it enables the warnings)
The following program illustrates the issue:
Makefile:
CFLAGS = -O3 -std=c++0x
LDFLAGS = -lreadline
test: test.o
g++ $(CFLAGS) $< $(LDFLAGS) -o $#
test.o: test.cpp Makefile
g++ $(CFLAGS) -c $<
test.cpp:
#include <fnmatch.h>
#include <readline/readline.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
static double time()
{
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return ts.tv_sec + (1e-9 * (double)ts.tv_nsec);
}
static void time_fnmatch()
{
for (int i = 0; i < 2; i++)
{
double t = time();
for (int i = 0; i < 1000000; i++)
{
fnmatch("*.o", "testfile", FNM_PERIOD);
}
fprintf(stderr, "%f\n", time()-t);
}
}
int main()
{
time_fnmatch();
char *input = readline("> ");
free(input);
time_fnmatch();
}
Output:
0.045371
0.044537
>
0.185246
0.181607
Before calling readline(), the fnmatch calls are about 4x faster. Although
this performance difference is worrying, I'm most interested in finding out
what exactly the readline() call might be doing to the program state that
would have this effect on other library calls.
Just a guess: readline initialization probably calls setlocale.
When a program starts up, it is in the C locale; a call to setlocale(LC_ALL, "") will enable the default locale, and these days, the default locale usually uses UTF-8, in which case many string operations become more complex. (Even just iterating over a string.)
I have the following simple program involving pthread and semaphore. I am in osx Maverck 10.9. I use a makefile to compile the program (rather than xcode). I use c++11.
#include <pthread.h>
#include <semaphore.h>
#include <cassert>
#include <iostream>
#define ASSERT(a) if(!(a)) abort
using namespace std;
sem_t countMutex;
int myCount=0;
void *doThread(void *data) {
int *pi = reinterpret_cast<int *>(data);
sem_wait(&countMutex);
for(int i =0 ;i < 100; ++i) {
myCount += 1;
}
sem_post(&countMutex);
pthread_exit( NULL );
}
void LaunchThread() {
const int kNumThreads = 10;
pthread_t tids[kNumThreads];
int threadData[kNumThreads];
pthread_attr_t attr;
pthread_t tid;
int retVal=0;
retVal = pthread_attr_init(&attr);
ASSERT(retVal == 0);
retVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE );
ASSERT(retVal == 0);
sem_init(&countMutex, 0, 1);
myCount = 0;
for(int i=0; i < kNumThreads; ++i) {
threadData[i] = i;
retVal = pthread_create( &tids[i], &attr, &doThread, &threadData[i]);
if(retVal != 0) {
cerr << "cannot create thread" << endl;
return;
}
}
retVal = pthread_attr_destroy(&attr);
ASSERT(retVal == 0);
void *status = NULL;
for(int i=0; i < kNumThreads; ++i) {
retVal = pthread_join( tids[i], &status);
if(retVal != 0) {
cerr << "cannot join ghread " << i << ", " << tids[i] << endl;
return;
}
cout << "completed thread " << i << ", " << tids[i] << endl;
}
cout << "value of myCount: " << myCount << endl;
sem_destroy(&countMutex);
//sem_unlink(&countMutex);
pthread_exit( NULL );
}
int main( int argc, char **argv) {
LaunchThread();
return 0;
}
The makefile for compiling this is
CXX=clang++
CXXFLAGS=-g -Wall -Wno-deprecated -std=c++11 -pthread -D DEBUG -g3 $(INCLUDES)
LDFLAGS=$(LIBS)
OBJS=main.o
PROG=test
all: $(PROG)
$(PROG): $(OBJS)
$(CXX) -v -o $(PROG) main.o $(LDFLAGS)
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $<
clean:
rm $(OBJS); rm test
The program ought to have reported a value of 1000 for myCount. But is inconsistent, on multiple runs.
Eg:
completed thread 0, 0x107dca000
completed thread 1, 0x107e4d000
completed thread 2, 0x107ed0000
completed thread 3, 0x107f53000
completed thread 4, 0x107fd6000
completed thread 5, 0x108059000
completed thread 6, 0x1080dc000
completed thread 7, 0x10815f000
completed thread 8, 0x1081e2000
completed thread 9, 0x108265000
value of myCount: 900
Unnamed POSIX semaphores are not supported on OSX. If you check your return codes you will see sem_init fail with an error along those lines. You need to use named semaphores.
Use sem_open instead of sem_init. Don't use sem_destroy but rather sem_close and sem_unlink.
You will be good to go.
I face a error of "multiple definition of "
I got 3 files, namely currency.h, currency.cpp,main.cpp
At currencyConverter.h under currencyConverter class
I did
using namespace std;
class currencyConverter
{
string result;
stringstream ss;
size_t found,found2;
public:
void getInbetween(string,string);
};
#endif /* CURRENCYCONVERTER_H */
Then at currencyConverter.cpp I did
#include "currencyConverter.h"
void currencyConverter::getInbetween(string selection,string str2,string str3,string sdata)
{
buffer[result.length()] = '\0'; //insert '\0'
char * pch;
pch = strtok (buffer," ");
}
void currencyConverter::webparser(const string siteurl,const string filename)
{
ss << "lynx -dump '" << siteurl << "' > " << filename;
}
string currencyConverter::userOption()
{
//some code
return selection;
}
at main2.cpp
#include<iostream>
#include"currencyConverter.cpp"
using namespace std;
int main() {
currencyConverter c;
string exitstr;
if(selection!="6")
{
c.webparser(parsePage,"file.txt");
//now perform searchstring
c.searchString(selection,"file.txt");
}
}while (1);
return 0;
}
This is my make file
# ExampleTests Project
SRCS = main2.cpp
HDRS =
PROJ = main
CC = g++
OBJS = $(SRCS:.cpp=.o)
APP = $(PROJ).exe
CFLAGS = -c -g -Wall -I/opt/local/include
ifeq (,$(findstring CYGWIN,$(shell uname)))
LIBS = -lcppunit -ldl
all: $(APP)
$(APP): $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $(APP) $(LIBS)
clean:
rm -f *.o $(APP)
But i receive this error on compiler
How to get this fix.. I did not use it twice. I pasted part of my currencyConverter.cpp with the function webparser, is there a error in the way i call my function at main2.cpp ?
rm -f *.o main.exe
CLEAN SUCCESSFUL (total time: 86ms)
g++ -c -o main2.o main2.cpp
td::char_traits, std::allocator >)':
currencyConverter.cpp:(.text+0xcec): multiple definition of `currencyConverter::webparser(std::basic_string, std::allocator >, std::basic_string, std::allocator >)'
main2.o:main2.cpp:(.text+0xcec): first defined here
collect2: ld returned 1 exit status
make: * [main.exe] Error 1
Include a header file, not a cpp:
#include"currencyConverter.cpp"
should be
#include"currencyConverter.h"
in your main2.cpp
I started doing threads about an hour ago and am having some trouble where the debug mode does what I expect and the release mode cashes.
Debug
g++ -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/foo.o.d -o build/Debug/GNU-Linux-x86/foo.o foo.cpp
Whatever 2222222222
Release
g++ -c -O2 -MMD -MP -MF build/Release/GNU-Linux-x86/foo.o.d -o build/Release/GNU-Linux-x86/foo.o foo.cpp
Whatever
RUN FAILED (exit value 1, total time: 49ms)
Class
#include "foo.h"
#define NUMINSIDE 10
foo::foo()
{
inside = new int[NUMINSIDE];
}
void foo::workerFunc(int input)
{
for (int i = 0; i < NUMINSIDE; i++)
{
inside[i] += input;
}
}
void foo::operate()
{
std::cout << "Whatever" << std::endl;
boost::thread thA(boost::bind(&foo::workerFunc, this, 1));
boost::thread thB(boost::bind(&foo::workerFunc, this, 1));
thA.join();
thB.join();
for (int i = 0; i < NUMINSIDE; i++)
{
std::cout << this->inside[i] << std::endl;
}
}
main
int main(int argc, char** argv)
{
foo* myFoo = new foo();
myFoo->operate();
return 0;
}
You have not initialized inside array. Add initialization code to foo::foo()
foo::foo()
{
inside = new int[NUMINSIDE];
for (int i = 0; i < NUMINSIDE; i++)
{
inside[i] = 0;
}
}
It works only in debug because it is undefined behavior.