I have generated a bc file with the online compiler on llvm.org, and I would like to know if it is possible to load this bc file from a c or c++ program, execute the IR in the bc file with the llvm jit (programmatically in the c program), and get the results.
How can I accomplish this?
Here's some working code based on Nathan Howell's:
#include <string>
#include <memory>
#include <iostream>
#include <llvm/LLVMContext.h>
#include <llvm/Target/TargetSelect.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ModuleProvider.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/ExecutionEngine/JIT.h>
using namespace std;
using namespace llvm;
int main()
{
InitializeNativeTarget();
llvm_start_multithreaded();
LLVMContext context;
string error;
Module *m = ParseBitcodeFile(MemoryBuffer::getFile("tst.bc"), context, &error);
ExecutionEngine *ee = ExecutionEngine::create(m);
Function* func = ee->FindFunctionNamed("main");
typedef void (*PFN)();
PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func));
pfn();
delete ee;
}
One oddity was that without the final include, ee is NULL. Bizarre.
To generate my tst.bc, I used http://llvm.org/demo/index.cgi and the llvm-as command-line tool.
This should (more or less) work using LLVM 2.6. It looks like there are some more helper functions in SVN to create a lazy ModuleProvider on top of a bitcode file. I haven't tried compiling it though, just glued together some bits from one of my JIT applications.
#include <string>
#include <memory>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ModuleProvider.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/ExecutionEngine/JIT.h>
using namespace std;
using namespace llvm;
int main()
{
InitializeNativeTarget();
llvm_start_multithreaded();
LLVMContext context;
string error;
auto_ptr<MemoryBuffer> buffer(MemoryBuffer::getFile("bitcode.bc"));
auto_ptr<Module> module(ParseBitcodeFile(buffer.get(), context, &error));
auto_ptr<ModuleProvider> mp(new ExistingModuleProvider(module));
module.release();
auto_ptr<ExecutionEngine> ee(ExecutionEngine::createJIT(mp.get(), &error));
mp.release();
Function* func = ee->getFunction("foo");
typedef void (*PFN)();
PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func));
pfn();
}
From the command line, you can use the LLVM program lli to run a bc file. If the file is in LLVM assembly language, you'll have to run llvm-as on it first to create a binary bitcode file.
It is easy to do this from C. I'd recommend you look at the extensive LLVM documentation: http://llvm.org/docs
The LLVM irc channel, which has a link on that page, is full of very knowledgeable people that are willing to answer questions.
Sorry for the indirect answer. I use LLVM extensively, but I do direct code generation not just in time compliation.
Related
I've been hiding under the MFC rock for many years so I can stick to standard C++ but still write Windows Desktop apps. With C++/WinRT and WinUI 3.0, it appears that I may finally have an opportunity to modernize my code. The problem is that I know nothing about XAML or the Windows API. To fix this problem, I'm trying to work my way through Petzold's "Programming Windows, 6th ed.", replacing the C# code with C++/WinRT. When all I have to do is write XAML, all is copacetic. However, when I get to p. 24, I'm supposed to adjust TextBlock properties in code. Here's the C#:
TextBlock tb = new TextBlock();
tb.Text = "Hello, Windows 8!";
tb.FontFamily = new FontFamily("Times New Roman");
tb.FontSize = 96;
tb.FontStyle = FontStyle.Italic;
...
and here's my attempt at a replacement:
TextBlock tb;
tb.Text(L"Hello, Windows 8!");
tb.FontFamily(FontFamily(L"Times New Roman"));
tb.FontSize(96);
tb.FontStyle(FontStyle::Italic);
...
All goes well until the last line. "FontStyle::Italic" is not recognized. I have similar issues with the enums for Color and HorizontalAlignment. What is the correct way to access these enums? Have I forgotten an include or a "using"? Here's what I currently have:
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.ApplicationModel.Activation.h>
#include <winrt/Microsoft.UI.Composition.h>
#include <winrt/Microsoft.UI.Text.h>
#include <winrt/Microsoft.UI.Xaml.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
#include <winrt/Microsoft.UI.Xaml.Data.h>
#include <winrt/Microsoft.UI.Xaml.Interop.h>
#include <winrt/Microsoft.UI.Xaml.Markup.h>
#include <winrt/Microsoft.UI.Xaml.Media.h>
#include <winrt/Microsoft.UI.Xaml.Navigation.h>
#include <winrt/Microsoft.UI.Xaml.Shapes.h>
and
using namespace winrt;
using namespace Microsoft::UI::Text;
using namespace Microsoft::UI::Xaml::Controls;
using namespace Microsoft::UI::Xaml::Controls::Primitives;
using namespace Microsoft::UI::Xaml::Media;
I hope there's a short answer to my long question.
To be sure, you'd need to post a little more detail (like what error message you're getting). But I'll take a guess that perhaps your code is missing a namespace qualifier. I'm just going off the UWP Windows namespace types, not the WinUI Microsoft namespace, but this code builds for me:
#include <winrt/Windows.UI.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Xaml.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Media.h>
void f()
{
winrt::Windows::UI::Xaml::Controls::TextBlock tb;
tb.Text(L"Hello");
tb.FontFamily(winrt::Windows::UI::Xaml::Media::FontFamily(L"Times New Roman"));
tb.FontSize(96);
tb.FontStyle(winrt::Windows::UI::Text::FontStyle::Italic);
tb.SelectionHighlightColor(winrt::Windows::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::Red()));
tb.HorizontalAlignment(winrt::Windows::UI::Xaml::HorizontalAlignment::Center);
}
As does this:
#include <winrt/Windows.UI.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Xaml.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Media.h>
using namespace winrt;
using namespace winrt::Windows::UI;
using namespace winrt::Windows::UI::Text;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Media;
void f()
{
TextBlock tb;
tb.Text(L"Hello");
tb.FontFamily(FontFamily(L"Times New Roman"));
tb.FontSize(96);
tb.FontStyle(FontStyle::Italic);
tb.SelectionHighlightColor(SolidColorBrush(Colors::Red()));
tb.HorizontalAlignment(HorizontalAlignment::Center);
}
The problem is that I don't what to write C code. I have some libraries - for example for building suffix automaton for a given text and it is much more comfortable to write this with C++. Then I want to write swift app with such class, but how to do it without writing C code and without some restrictions on using C++ code. For example
in my test.cpp I have
#include "test.h"
#include <string>
std::string hello() {
return "Hello";
}
In my bridge I have:
#include "test.h"
But there is problems with test.h.
Without using C I can't just write
#include <string>
std::string hello();
I'm using Crypto++ to encrypt files in C++. And I'm using the code below.
It doesn't contain the headers files so I added my own :
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>
#include <cryptopp/cryptlib.h>
#include <cryptopp/sha.h>
#include <cryptopp/secblock.h>
#include <cryptopp/files.h>
#include <cryptopp/queue.h>
#include <cryptopp/hex.h>
#include <cryptopp/base64.h>
#include <cryptopp/filters.h>
#include <cryptopp/osrng.h>
#include <cryptopp/integer.h>
#include <cryptopp/dh.h>
#include <cryptopp/sha.h>
#include <cryptopp/modes.h>
#include <cryptopp/eax.h>
#include <cryptopp/tea.h>
#include <cryptopp/blowfish.h>
#include <cryptopp/pssr.h>
#include <cryptopp/rsa.h>
#include <cryptopp/nbtheory.h>
#include <cryptopp/eccrypto.h>
#include <cryptopp/oids.h>
#include <cryptopp/modes.h>
#include <cryptopp/gzip.h>
#include <cryptopp/blowfish.h>
#include <cryptopp/rsa.h>
#include <cryptopp/rng.h>
#include <cryptopp/cryptlib.h>
#include <cryptopp/filters.h>
#include <cryptopp/rdrand.h>
using namespace std;
using namespace CryptoPP;
But unfortunately the code doesn't work
Saying that the GlobalRNG is not declared !
error: ‘GlobalRNG’ was not declared in this scope
I googled and kept looking for a solution for 2 days i found that it's a bug and fixed but i'm having the latest version : 5.6.3 !
So i really don't know why this error is showing !
In the version 5.6.3 GlobalRNG is defined in the file validate.h, as:
// Functions that need a RNG; uses AES inf CFB mode with Seed.
CryptoPP::RandomNumberGenerator & GlobalRNG();
Just add this inclusion:
#include <cryptopp/validate.h>
to solve definition problem.
GloablaRNG is part of testing and bench-marking. It should not be part of the library proper (i.e., libcryptopp.a or libcryptopp.so). If your programs are complaining about a missing GloablaRNG, then the library was cross-contaminated with some of the testing and bench-marking gear.
These are the files used for testing and bench-marking. They should not be included in your build of the library or your project:
validate.h
bench.h
test.cpp
bench1.cpp, bench2.cpp
validat0.cpp, validat1.cpp, validat2.cpp, validat3.cpp
datatest.cpp, regtest.cpp, fipsalgt.cpp, dlltest.cpp
You are free to use a function called GlobalRNG(). Here's how its used in the library's test and bench-marking gear. But you might consider using an AutoSeededRandomPool instead. The AutoSeededRandomPool is a PGP-style generator, and its seeded from /dev/urandom, /dev/srandom, /dev/random or the Windows entropy pool.
Declaration in validate.h
NAMESPACE_BEGIN(CryptoPP)
NAMESPACE_BEGIN(Test)
CryptoPP::RandomNumberGenerator & GlobalRNG();
NAMESPACE_END // Test
NAMESPACE_END // CryptoPP
Definition in test.cpp
NAMESPACE_BEGIN(CryptoPP)
NAMESPACE_BEGIN(Test)
ANONYMOUS_NAMESPACE_BEGIN
OFB_Mode<AES>::Encryption s_globalRNG;
NAMESPACE_END
RandomNumberGenerator & GlobalRNG()
{
return dynamic_cast<RandomNumberGenerator&>(s_globalRNG);
}
NAMESPACE_END // Test
NAMESPACE_END // CryptoPP
Seeding in test.cpp
// Don't do this in production because it creates a deterministic generator
OFB_Mode<AES>::Encryption& aesg = dynamic_cast<OFB_Mode<AES>::Encryption&>(Test::GlobalRNG());
aesg.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
A lot of folks have had this problem over the years. At Crypto++ 6.0, we moved GlobalRNG() into the Test namespace. Test is a new namespace, and we hope Test::GlobalRNG() will provide the signals that something is amiss in your library build or project configuration.
Also see Issue 379, Add Test namespace within CryptoPP namespace and Commit 73836e58a5f5c11c.
I starting my first GNU project based on another GNU project to improve upon it and change the implementation.
I tried to implement my own build method, but time- and clock-related functions broke my build.
I've read a lot of questions on Stack Overflow, but I very confused with the three libraries chrono, ctime and time.h.
This is the build errors:
/src/gamed/Logger.cpp
#include "Logger.h"
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
const std::string Logger::CurrentDateTime()
{
time_t now = time(0);
struct tm tstruct;
char buf[80];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%Y-%m-%d %X", &tstruct);
return buf;
}
Error: time, localtime and strftime identifier not found
/src/gamed/Packets.h
#ifndef _PACKETS_H
#define _PACKETS_H
#include <time.h>
#include <cmath>
#include <set>
{...}
class GamePacket : public BasePacket {
public:
GamePacket(uint8 cmd = 0, uint32 netId = 0) : BasePacket(cmd, netId) {
buffer << (uint32)clock();
}
};
Error: clock identifier not found
/src/gamed/Pathfinder.cpp
#include "Logger.h"
#include "Pathfinder.h"
#include "Map.h"
#include "AIMesh.h"
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <chrono>
#include "Logger.h"
#include "Minion.h"
#include "Champion.h"
Map * Pathfinder::chart = 0;
auto g_Clock = std::clock();
Error: clock isn't member of std
What am I doing wrong?
I very confused with the three libraries chrono, ctime and time.h.
There's only 2 libraries in that sentence. <chrono> is part of the c++ standard library and was introduced in c++11 version of the standard. None of your code seem to use anything from <chrono>. <time.h> is part of the c standard library. <ctime> is a header in c++ standard library which wraps <time.h> inside std namespace instead of global namespace which is the only "namespace" in c.
#include <time.h>
// ....
auto g_Clock = std::clock();
Error: clock isn't member of std
You included the c header but try to refer to the std namespace. That is not correct. Include <ctime> instead so that clock will be in std.
#include <time.h>
// ...
time_t now = time(0);
Error: time (...) identifier not found
At a glance, your code there seems correct. Double check that's actually the code you're compiling and getting the errors from. Here's simplified version of that function which compiles fine http://coliru.stacked-crooked.com/a/664f568053103f32
Stylewise, I wouldn't recommend mixing <cXXX> and <XXX.h> headers. Pick one.
Solved!
The problem is the project use enet library, and has time.h, renaming file to enet_time.h the build work great (It's temporary fix, I think is better using namespaces).
Thanks to all and sorry for the inconvenients, I learn more of wrapping C libraries into C++ thanks to all responses.
A greeting
In C++ you should use the "c" prefix on all your C-library #includes.
So #include <time.h> should become: #include <ctime>.
But note that when you use #include <ctime> everything in time.h will now be in the std namespace.
So clock() must become std::clock().
For more info see: http://www.parashift.com/c++-faq/include-c-hdrs-system.html
I have built the LLVM using CMake using VS 2012 in keeping with documentation. I am trying to build a toy compiler with flex, bison and LLVM. The final stage of my compiler my main class looks like this:
#include <iostream>
#include "codegen.h"
#include "node.h"
#include "llvm/Target/Targetmachine.h"
using namespace std;
extern int yyparse();
extern NBlock* programBlock;
void createCoreFunctions(CodeGenContext& context);
int main(int argc, char **argv)
{
yyparse();
std::cout << programBlock << endl;
InitializeNativeTarget();
CodeGenContext context;
createCoreFunctions(context);
context.generateCode(*programBlock);
context.runCode();
return 0;
}
As stated in my previous post LLVM 3.4 linker errors in VS 2012. To workaround the solution I manually added the x86 files I was missing (taking clue from the errors). I ended up adding the following to the main:
#include "llvm-3.4/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h"
#include "llvm-3.4/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h"
#include "llvm-3.4/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h"
#include "X86MCAsmInfo.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetRegistry.h"
#include "X86GenRegisterInfo.inc"
#include "X86GenInstrInfo.inc"
#include "X86GenSubtargetInfo.inc"
But I noticed that the following are missing from my system:
"X86MCAsmInfo.h"
"X86GenRegisterInfo.inc"
"X86GenInstrInfo.inc"
"X86GenSubtargetInfo.inc"
I looked through the online documentation but I am a beginner on the topic, most of it did not make too much sense to me. I would appreciate if someone could guide me or point me to the right tutorial which gives me a better understanding of what I am doing wrong here.