Has anyone ever did a python to LLVM to IR to VHDL compiler ??? Has anyone
used LLVM to ultimately create a Python to VHDL compiler ???
Thanks,
David Blubaugh
On Monday, September 1, 2014 8:35 PM, "llvmdev-request at cs.uiuc.edu"
<llvmdev-request at cs.uiuc.edu> wrote:
Send LLVMdev mailing list submissions to
llvmdev at cs.uiuc.edu
To subscribe or unsubscribe via the World Wide Web, visit
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
or, via email, send a message with subject or body 'help' to
llvmdev-request at cs.uiuc.edu
You can reach the person managing the list at
llvmdev-owner at cs.uiuc.edu
When replying, please edit your Subject line so it is more specific
than "Re: Contents of LLVMdev digest..."
Today's Topics:
1. VMKit is retired (but you can help if you want!) (Ga?l Thomas)
2. Instrumenting Various Types Using Single Instrumentation
Function (Manish Gupta)
3. Problem linking and JITing code through C++-API (Andy Jost)
4. Re: Instrumenting Various Types Using Single Instrumentation
Function (John Criswell)
5. Fwd: understanding DAG: node creation (Dmitri Kovalenko)
----------------------------------------------------------------------
Message: 1
Date: Mon, 1 Sep 2014 21:34:58 +0200
From: Ga?l Thomas <gael.thomas00 at gmail.com>
To: LLVM Developers Mailing List <llvmdev at cs.uiuc.edu>, Nicolas
Geoffray <nicolas.geoffray at gmail.com>
Subject: [LLVMdev] VMKit is retired (but you can help if you want!)
Message-ID:
<CAOWuPDcZBpt_JJ5yo5YN=C+RWbtbneXB1UGd90d0mXdnrs8=RQ at
mail.gmail.com>
Content-Type: text/plain; charset=UTF-8
Hi all,
So, as explained in the LLVM weekly, the VMKit project is retired. It
was a very fun project, but we don't have any manpower to maintain the
code since one year. If someone is interested by restarting the
project, just send me an email, I can help to understand the
architecture of the project and how it works. I'm pretty sure that we
can also extract a Java to LLVM compiler easily (I know that some
people are interested by that).
And I want to thank all the LLVM team for their support during these
last ten (yes ten:)) years! Without their help, it would have been
impossible to develop VMKit.
See you and thank you!
Ga?l
------------------------------
Message: 2
Date: Mon, 1 Sep 2014 13:50:53 -0700
From: Manish Gupta <manishg at cs.ucsd.edu>
To: llvmdev <llvmdev at cs.uiuc.edu>
Subject: [LLVMdev] Instrumenting Various Types Using Single
Instrumentation Function
Message-ID:
<CAL6s+Wn0zEnUpa3ze2vMdO03PJi+8s-xo_TeOmWgoExc8xmHwg at
mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Hi All,
My instrumentation code needs to insert calls to transmit Value list. Each
element in this list could be of different type. The list is sent to
instrumenting function say void recordVarInputValues(int num, ...) . So, I
have created a Union type in Tracing.cpp, which I link with my benchmark
module at compile time. These steps are similar to giri instrumentation
https://github.com/liuml07/giri
union NumericType
{
int iValue;
long lValue;
double dValue;
...
};
Now, I would like to convert all the llvm Values, required by
recordVarInputValues function, to be of NumericType. So that a variable
length list of NumerricType values can be passed to my instrumentation
function. This way I will not have to create different instrumentation
functions for different data types.
Can I cast say i32 value to NumericType value in my instrumentation code,
without inserting additional instructions in my benchmark code. I tried
inserting bitcast instructions and it doesn't work for me...
if(!CastInst::isCastable(Lvals[j]->getType(), UnionVar->getType())){
errs()<<"CAST TO NumericType NOT POSSIBLE\n";
exit(0);
}
CastInst *I = CastInst::CreateZExtOrBitCast(Lvals[j],
UnionVar->getType(), "", F);
Is this even possible or some other method will be better?
Thanks!
Manish
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.cs.uiuc.edu/pipermail/llvmdev/attachments/20140901/7454021b/attachment-0001.html>
------------------------------
Message: 3
Date: Mon, 1 Sep 2014 23:41:32 +0000
From: Andy Jost <Andrew.Jost at synopsys.com>
To: "LLVMdev at cs.uiuc.edu" <LLVMdev at cs.uiuc.edu>
Subject: [LLVMdev] Problem linking and JITing code through C++-API
Message-ID:
<CD79F295D495814684E75D6407C8476284668853 at
US01WEMBX2.internal.synopsys.com>
Content-Type: text/plain; charset="us-ascii"
I have a frontend that generates some LLVM bitcode that needs to be linked with
other bitcode (its runtime library), which I generate from C++ source using
Clang.
If I write the output of my program to disk, link it with llvm-link, and then
run it with lli, everything works perfectly. But if I try to perform the
linking and running steps in my main program, I get this error during
llvm::ExecutionEngine::getPointerToFunction:
Stack dump:
0. Running pass 'X86 Machine Code Emitter' on function
'@.step.myappend'
1. Running pass 'X86 Machine Code Emitter' on function
'@.step.myappend'
Segmentation fault (core dumped)
There are no other messages. Any idea what I'm doing wrong? I'll copy
the source of my main C++ file and the bitcode for .step.myappend below. I can
send the full bitcode file, too, if someone asks for it, but it is around 800
lines.
####################
#include <fstream>
#include <iostream>
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Linker.h"
#include "llvm/PassManager.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "sprite/compiler.hpp"
#include "sprite/config.hpp"
#include "sprite/curryinput.hpp"
#include "sprite/icurry_parser.hpp"
namespace
{
std::string dirname(std::string const & path)
{
size_t const pos = path.find_last_of("/");
return path.substr(0, pos == std::string::npos ? 0 : pos);
}
std::string basename(std::string const & path)
{
size_t const pos = path.find_last_of("/");
return path.substr(pos == std::string::npos ? 0 : pos + 1);
}
std::string remove_extension(std::string const & path)
{
size_t const pos = path.find_last_of(".");
return pos == std::string::npos ? path : path.substr(0, pos);
}
std::string joinpath(std::string const & dirname, std::string const &
path)
{
if(!path.empty() && path.front() == '/')
return path;
if(dirname.empty())
return path;
return dirname.back() == '/' ? dirname + path : dirname +
"/" + path;
}
}
int main(int argc, char const *argv[])
{
if(argc != 2)
{
std::cerr << "Usage: " << argv[0] << "
<file.curry>" << std::endl;
return 1;
}
std::string const curry2read std::string(SPRITE_LIBINSTALL) +
"/cmc/translator/bin/curry2read";
std::string const curryfile(argv[1]);
std::string const readablefile = joinpath(
dirname(curryfile)
, ".curry/" + remove_extension(basename(curryfile)) +
".read"
);
// Generate the readable Curry file.
int ok = std::system((curry2read + " -q " + curryfile).c_str());
if(ok != 0) return 1;
std::ifstream input(readablefile);
if(!input)
{
std::cerr << "Could not open \"" << readablefile
<< "\"" << std::endl;
return 1;
}
// Parse the input program.
sprite::curry::Library lib;
input >> lib;
std::string topmodule = lib.modules.front().name;
// sprite::compiler::prettyprint(lib);
// Compile the program.
sprite::compiler::LibrarySTab stab;
sprite::compiler::compile(lib, stab);
// Declare the main function.
namespace tgt = sprite::backend;
auto & module_stab = stab.modules.at(topmodule);
auto & compiler = *module_stab.compiler;
tgt::scope _ = module_stab.module_ir;
tgt::extern_(
tgt::types::int_(32)(), "main", {}
, [&]{
// Construct the root expression (just the "main" symbol).
tgt::value root_p = compiler.node_alloc();
sprite::curry::Qname const main_{topmodule, "main"};
root_p = construct(compiler, root_p, {main_, {}});
// Evaluate and then print the root expression.
compiler.rt.normalize(root_p);
compiler.rt.printexpr(root_p, "\n");
tgt::return_(0);
}
);
// module_stab.module_ir->dump();
// Load the runtime library.
llvm::OwningPtr<llvm::MemoryBuffer> buffer;
llvm::error_code err = llvm::MemoryBuffer::getFile(
SPRITE_LIBINSTALL "/sprite-rt.bc", buffer
);
if(err)
{
std::cerr << err.message() << std::endl;
return EXIT_FAILURE;
}
// Make the runtime library into a module.
std::string errmsg;
llvm::Module *rtlib = llvm::ParseBitcodeFile(
buffer.get(), module_stab.module_ir.context(), &errmsg
);
if(!rtlib)
{
std::cerr << errmsg << std::endl;
return EXIT_FAILURE;
}
// Link the compiled program code into the runtime module.
bool failed = llvm::Linker::LinkModules(
rtlib, module_stab.module_ir.ptr(), llvm::Linker::PreserveSource,
&errmsg
);
if(failed)
{
std::cerr << errmsg << std::endl;
return EXIT_FAILURE;
}
std::cout << "Linking done..." << std::endl;
rtlib->dump();
// Run optimization passes.
// std::vector<const char *> exportList;
// llvm::PassManager Passes;
// Passes.add(new llvm::DataLayout(rtlib));
// Passes.add(llvm::createDemoteRegisterToMemoryPass());
// Passes.add(llvm::createInternalizePass(exportList));
// Passes.add(llvm::createScalarReplAggregatesPass());
// Passes.add(llvm::createInstructionCombiningPass());
// Passes.add(llvm::createGlobalOptimizerPass());
// Passes.add(llvm::createFunctionInliningPass());
// Passes.run(*rtlib);
// Create the JIT
llvm::InitializeNativeTarget();
llvm::ExecutionEngine * jit = llvm::EngineBuilder(rtlib)
.setErrorStr(&errmsg)
.setEngineKind(llvm::EngineKind::JIT)
.create();
if(!jit)
{
std::cerr << "Failed to create JIT compiler: " <<
errmsg << std::endl;
return EXIT_FAILURE;
}
// Execute the program.
std::cout << "Begin Execution..." << std::endl;
// rtlib->dump();
void * main_fp =
jit->getPointerToFunction(rtlib->getFunction("main"));
int32_t (*target_program)() = (int32_t(*)())(intptr_t)(main_fp);
std::cout << "Ready..." << std::endl;
return target_program();
#if 0
// Write a bitcode file and interpret it.
{
std::string err;
llvm::raw_fd_ostream fout("sprite-out.bc", err,
llvm::raw_fd_ostream::F_Binary);
llvm::WriteBitcodeToFile(module_stab.module_ir.ptr(), fout);
}
std::system("llvm-link-3.3 sprite-out.bc " SPRITE_LIBINSTALL
"/sprite-rt.bc > tmp.bc");
std::system("mv tmp.bc sprite-out.bc");
int const status = std::system("lli-3.3 sprite-out.bc");
return WEXITSTATUS(status);
#endif
}
####################
define linkonce void @.step.myappend(%"struct.sprite::compiler::node"*
%root_p) {
.entry:
%0 = alloca %"struct.sprite::compiler::node"*
%1 = alloca %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %root_p,
%"struct.sprite::compiler::node"** %0
%2 = load %"struct.sprite::compiler::node"** %0
%3 = getelementptr %"struct.sprite::compiler::node"* %2, i32 0, i32
2
%4 = load i8** %3
%5 = bitcast i8* %4 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %5,
%"struct.sprite::compiler::node"** %0
br label %11
; <label>:6 ; preds = %11
%7 = load %"struct.sprite::compiler::node"** %0
%8 = getelementptr %"struct.sprite::compiler::node"* %7, i32 0, i32
2
%9 = load i8** %8
%10 = bitcast i8* %9 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %10,
%"struct.sprite::compiler::node"** %0
br label %11, !sprite.implied !0
; <label>:11 ; preds = %6, %.entry
%12 = load %"struct.sprite::compiler::node"** %0
%13 = getelementptr %"struct.sprite::compiler::node"* %12, i32 0,
i32 1
%14 = load i64* %13
%15 = load i64* %13
%16 = icmp eq i64 %15, -3
br i1 %16, label %6, label %17
; <label>:17 ; preds = %11
%18 = load %"struct.sprite::compiler::node"** %0
store %"struct.sprite::compiler::node"* %18,
%"struct.sprite::compiler::node"** %1
%19 = getelementptr %"struct.sprite::compiler::node"* %18, i32 0,
i32 1
%20 = load i64* %19
%21 = add i64 %20, 4
%22 = getelementptr [6 x i8*]* @.jtable, i32 0, i64 %21
%23 = load i8** %22
indirectbr i8* %23, [label %24, label %26, label %36, label %38, label %44,
label %66]
; <label>:24 ; preds = %26, %17
%25 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x i8]*
@.str21, i32 0, i32 0))
ret void, !case...FAIL !1
; <label>:26 ; preds = %26, %17
%27 = load %"struct.sprite::compiler::node"** %1
%28 = getelementptr %"struct.sprite::compiler::node"* %27, i32 0,
i32 2
%29 = load i8** %28
%30 = bitcast i8* %29 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %30,
%"struct.sprite::compiler::node"** %1
%31 = getelementptr %"struct.sprite::compiler::node"* %30, i32 0,
i32 1
%32 = load i64* %31
%33 = add i64 %32, 4
%34 = getelementptr [6 x i8*]* @.jtable, i32 0, i64 %33
%35 = load i8** %34
indirectbr i8* %35, [label %24, label %26, label %36, label %38, label %44,
label %66]
; <label>:36 ; preds = %26, %17
%37 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]*
@.str22, i32 0, i32 0))
ret void, !case...CHOICE !1
; <label>:38 ; preds = %26, %17
%39 = load %"struct.sprite::compiler::node"** %1
%40 = getelementptr %"struct.sprite::compiler::node"* %39, i32 0,
i32 0
%41 = load %"struct.sprite::compiler::vtable"** %40
%42 = getelementptr %"struct.sprite::compiler::vtable"* %41, i32 0,
i32 4
%43 = load void (%"struct.sprite::compiler::node"*)** %42
tail call void %43(%"struct.sprite::compiler::node"* %39)
ret void
; <label>:44 ; preds = %26, %17
store %"struct.sprite::compiler::node"* %root_p,
%"struct.sprite::compiler::node"** %0
%45 = load %"struct.sprite::compiler::node"** %0
%46 = getelementptr %"struct.sprite::compiler::node"* %45, i32 0,
i32 3
%47 = load i8** %46
%48 = bitcast i8* %47 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %48,
%"struct.sprite::compiler::node"** %0
br label %54
; <label>:49 ; preds = %54
%50 = load %"struct.sprite::compiler::node"** %0
%51 = getelementptr %"struct.sprite::compiler::node"* %50, i32 0,
i32 2
%52 = load i8** %51
%53 = bitcast i8* %52 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %53,
%"struct.sprite::compiler::node"** %0
br label %54, !sprite.implied !0
; <label>:54 ; preds = %49, %44
%55 = load %"struct.sprite::compiler::node"** %0
%56 = getelementptr %"struct.sprite::compiler::node"* %55, i32 0,
i32 1
%57 = load i64* %56
%58 = load i64* %56
%59 = icmp eq i64 %58, -3
br i1 %59, label %49, label %60
; <label>:60 ; preds = %54
%61 = load %"struct.sprite::compiler::node"** %0
%62 = bitcast %"struct.sprite::compiler::node"* %61 to i8*
%63 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
0, i32 0
store %"struct.sprite::compiler::vtable"* @.fwd.vt,
%"struct.sprite::compiler::vtable"** %63
%64 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
0, i32 1
store i64 -3, i64* %64
%65 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
0, i32 2
store i8* %62, i8** %65
ret void
; <label>:66 ; preds = %26, %17
store %"struct.sprite::compiler::node"* %root_p,
%"struct.sprite::compiler::node"** %0
%67 = load %"struct.sprite::compiler::node"** %0
%68 = getelementptr %"struct.sprite::compiler::node"* %67, i32 0,
i32 2
%69 = load i8** %68
%70 = bitcast i8* %69 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %70,
%"struct.sprite::compiler::node"** %0
br label %76
; <label>:71 ; preds = %76
%72 = load %"struct.sprite::compiler::node"** %0
%73 = getelementptr %"struct.sprite::compiler::node"* %72, i32 0,
i32 2
%74 = load i8** %73
%75 = bitcast i8* %74 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %75,
%"struct.sprite::compiler::node"** %0
br label %76, !sprite.implied !0
; <label>:76 ; preds = %71, %66
%77 = load %"struct.sprite::compiler::node"** %0
%78 = getelementptr %"struct.sprite::compiler::node"* %77, i32 0,
i32 1
%79 = load i64* %78
%80 = load i64* %78
%81 = icmp eq i64 %80, -3
br i1 %81, label %71, label %82
; <label>:82 ; preds = %76
%83 = load %"struct.sprite::compiler::node"** %0
%84 = getelementptr %"struct.sprite::compiler::node"* %83, i32 0,
i32 2
%85 = load i8** %84
%86 = bitcast i8* %85 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %86,
%"struct.sprite::compiler::node"** %0
br label %92
; <label>:87 ; preds = %92
%88 = load %"struct.sprite::compiler::node"** %0
%89 = getelementptr %"struct.sprite::compiler::node"* %88, i32 0,
i32 2
%90 = load i8** %89
%91 = bitcast i8* %90 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %91,
%"struct.sprite::compiler::node"** %0
br label %92, !sprite.implied !0
; <label>:92 ; preds = %87, %82
%93 = load %"struct.sprite::compiler::node"** %0
%94 = getelementptr %"struct.sprite::compiler::node"* %93, i32 0,
i32 1
%95 = load i64* %94
%96 = load i64* %94
%97 = icmp eq i64 %96, -3
br i1 %97, label %87, label %98
; <label>:98 ; preds = %92
%99 = load %"struct.sprite::compiler::node"** %0
%100 = bitcast %"struct.sprite::compiler::node"* %99 to i8*
%101 = call i8* @malloc(i64 32)
%102 = bitcast i8* %101 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %root_p,
%"struct.sprite::compiler::node"** %0
%103 = load %"struct.sprite::compiler::node"** %0
%104 = getelementptr %"struct.sprite::compiler::node"* %103, i32 0,
i32 2
%105 = load i8** %104
%106 = bitcast i8* %105 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %106,
%"struct.sprite::compiler::node"** %0
br label %112
; <label>:107 ; preds = %112
%108 = load %"struct.sprite::compiler::node"** %0
%109 = getelementptr %"struct.sprite::compiler::node"* %108, i32 0,
i32 2
%110 = load i8** %109
%111 = bitcast i8* %110 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %111,
%"struct.sprite::compiler::node"** %0
br label %112, !sprite.implied !0
; <label>:112 ; preds = %107, %98
%113 = load %"struct.sprite::compiler::node"** %0
%114 = getelementptr %"struct.sprite::compiler::node"* %113, i32 0,
i32 1
%115 = load i64* %114
%116 = load i64* %114
%117 = icmp eq i64 %116, -3
br i1 %117, label %107, label %118
; <label>:118 ; preds = %112
%119 = load %"struct.sprite::compiler::node"** %0
%120 = getelementptr %"struct.sprite::compiler::node"* %119, i32 0,
i32 3
%121 = load i8** %120
%122 = bitcast i8* %121 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %122,
%"struct.sprite::compiler::node"** %0
br label %128
; <label>:123 ; preds = %128
%124 = load %"struct.sprite::compiler::node"** %0
%125 = getelementptr %"struct.sprite::compiler::node"* %124, i32 0,
i32 2
%126 = load i8** %125
%127 = bitcast i8* %126 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %127,
%"struct.sprite::compiler::node"** %0
br label %128, !sprite.implied !0
; <label>:128 ; preds = %123, %118
%129 = load %"struct.sprite::compiler::node"** %0
%130 = getelementptr %"struct.sprite::compiler::node"* %129, i32 0,
i32 1
%131 = load i64* %130
%132 = load i64* %130
%133 = icmp eq i64 %132, -3
br i1 %133, label %123, label %134
; <label>:134 ; preds = %128
%135 = load %"struct.sprite::compiler::node"** %0
%136 = bitcast %"struct.sprite::compiler::node"* %135 to i8*
store %"struct.sprite::compiler::node"* %root_p,
%"struct.sprite::compiler::node"** %0
%137 = load %"struct.sprite::compiler::node"** %0
%138 = getelementptr %"struct.sprite::compiler::node"* %137, i32 0,
i32 3
%139 = load i8** %138
%140 = bitcast i8* %139 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %140,
%"struct.sprite::compiler::node"** %0
br label %146
; <label>:141 ; preds = %146
%142 = load %"struct.sprite::compiler::node"** %0
%143 = getelementptr %"struct.sprite::compiler::node"* %142, i32 0,
i32 2
%144 = load i8** %143
%145 = bitcast i8* %144 to %"struct.sprite::compiler::node"*
store %"struct.sprite::compiler::node"* %145,
%"struct.sprite::compiler::node"** %0
br label %146, !sprite.implied !0
; <label>:146 ; preds = %141, %134
%147 = load %"struct.sprite::compiler::node"** %0
%148 = getelementptr %"struct.sprite::compiler::node"* %147, i32 0,
i32 1
%149 = load i64* %148
%150 = load i64* %148
%151 = icmp eq i64 %150, -3
br i1 %151, label %141, label %152
; <label>:152 ; preds = %146
%153 = load %"struct.sprite::compiler::node"** %0
%154 = bitcast %"struct.sprite::compiler::node"* %153 to i8*
%155 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0,
i32 0
store %"struct.sprite::compiler::vtable"* @.vtable.for.myappend,
%"struct.sprite::compiler::vtable"** %155
%156 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0,
i32 1
store i64 -1, i64* %156
%157 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0,
i32 2
store i8* %136, i8** %157
%158 = getelementptr %"struct.sprite::compiler::node"* %102, i32 0,
i32 3
store i8* %154, i8** %158
%159 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
0, i32 0
store %"struct.sprite::compiler::vtable"* @.vt.CTOR.MyCons,
%"struct.sprite::compiler::vtable"** %159
%160 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
0, i32 1
store i64 1, i64* %160
%161 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
0, i32 2
store i8* %100, i8** %161
%162 = getelementptr %"struct.sprite::compiler::node"* %root_p, i32
0, i32 3
store i8* %101, i8** %162
ret void
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.cs.uiuc.edu/pipermail/llvmdev/attachments/20140901/52547f6a/attachment-0001.html>
------------------------------
Message: 4
Date: Mon, 01 Sep 2014 20:13:56 -0400
From: John Criswell <jtcriswel at gmail.com>
To: manishg at cs.ucsd.edu, llvmdev <llvmdev at cs.uiuc.edu>
Subject: Re: [LLVMdev] Instrumenting Various Types Using Single
Instrumentation Function
Message-ID: <54050BC4.8060405 at gmail.com>
Content-Type: text/plain; charset="iso-8859-1";
Format="flowed"
Dear Manish,
Union types in LLVM are points to structures, so casting 8, 16, 32, and
64 bit values to a union pointer is probably not what you want.
I think the easiest thing to do is to:
1) Change the function in your run-time library to take the largest
integer size supported by your target.
2) Change the instrumentation code to cast all values (including
pointers) to this type.
I'm not sure if CastInst::isCastable() is what you want to use to check
to see that the casting can be done. I would just go ahead and use the
bit-cast since, for the call, you should always be casting from a type
with lower bit-width to higher bit-width. If you enable assertions when
you build LLVM, then you should get an assertion if you try to create a
Bitcast instruction that isn't going to work.
Regards,
John Criswell
On 9/1/14, 4:50 PM, Manish Gupta wrote:> Hi All,
>
>
> My instrumentation code needs to insert calls to transmit Value list.
> Each element in this list could be of different type. The list is sent
> to instrumenting function say void recordVarInputValues(int num, ...)
> . So, I have created a Union type in Tracing.cpp, which I link with my
> benchmark module at compile time. These steps are similar to giri
> instrumentation https://github.com/liuml07/giri
>
> union NumericType
> {
> int iValue;
> long lValue;
> double dValue;
> ...
> };
>
> Now, I would like to convert all the llvm Values, required by
> recordVarInputValues function, to be of NumericType. So that a
> variable length list of NumerricType values can be passed to my
> instrumentation function. This way I will not have to create different
> instrumentation functions for different data types.
>
> Can I cast say i32 value to NumericType value in my instrumentation
> code, without inserting additional instructions in my benchmark code.
> I tried inserting bitcast instructions and it doesn't work for me...
>
> if(!CastInst::isCastable(Lvals[j]->getType(), UnionVar->getType())){
> errs()<<"CAST TO NumericType NOT POSSIBLE\n";
> exit(0);
> }
> CastInst *I = CastInst::CreateZExtOrBitCast(Lvals[j],
> UnionVar->getType(), "", F);
>
> Is this even possible or some other method will be better?
>
> Thanks!
> Manish
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.cs.uiuc.edu/pipermail/llvmdev/attachments/20140901/23a75e18/attachment-0001.html>
------------------------------
Message: 5
Date: Tue, 2 Sep 2014 04:26:52 +0400
From: Dmitri Kovalenko <dmitri.a.kovalenko at gmail.com>
To: "llvmdev at cs.uiuc.edu" <llvmdev at cs.uiuc.edu>
Subject: [LLVMdev] Fwd: understanding DAG: node creation
Message-ID:
<CAF+j+H_Q42PA63odeQOWwsuL6O-M2NRnB4bRn5ZxRq0Mn4rW+Q at
mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Sam, that helped. Thank you so much.
2014-09-01 19:04 GMT+04:00 Sam Parker <S.Parker3 at lboro.ac.uk>:
Hi,>
> I would still switch chain operands to be the last ones and ensure that
> lxacc result type is (MVT::i32, MVT::other) and not the other way around.
>
> good luck,
>
> sam
>
> Sam Parker
> Research Student
> Electronic System Design Group
> School of Electronic, Electrical and Systems Engineering
> Loughborough University
> UK
>
> On 01/09/14 15:39, Dmitri Kovalenko wrote:
>
> Yes, I'm going to provide it. I believe there must be no additional
> work on the scheduling phase. It's just some mistake in the instruction
> definition or DAG.
>
> I create Nodes inside SelectionDAGBuilder::visitIntrinicCall like that:
>
> case Intrinsic::sparc_xmac: {
> SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);
> SDValue Ops[3];
> Ops[0] = getRoot();
> Ops[1] = getValue(I.getArgOperand(0));
> Ops[2] = getValue(I.getArgOperand(1));
> SDValue xmacCall = DAG.getNode(ISD::XMAC, sdl, nodeTys, Ops);
> DAG.setRoot(xmacCall.getValue(0));
> return nullptr;
> }
> case Intrinsic::sparc_srxacc: {
> SDVTList nodeTys = DAG.getVTList(MVT::Other, MVT::i32);
> SDValue Ops[2];
> Ops[0] = getRoot();
> Ops[1] = getValue(I.getArgOperand(0));
> SDValue srCall = DAG.getNode(ISD::SRXACC, sdl, nodeTys, Ops);
> DAG.setRoot(srCall.getValue(0));
> return nullptr;
> }
> case Intrinsic::sparc_lrxacc: {
> SDVTList nodeTys = DAG.getVTList(MVT::Other,MVT::i32);
> SDValue Ops[1];
> Ops[0] = getRoot();
> SDValue lrCall = DAG.getNode(ISD::LRXACC, sdl,
> nodeTys, Ops);
> DAG.setRoot(lrCall.getValue(0));
> setValue(&I, lrCall.getValue(1));
> return nullptr;
> }
>
> Then, lower them trivially.
>
> setOperationAction(ISD::LRXACC, MVT::Other, Legal);
> setOperationAction(ISD::SRXACC, MVT::Other, Legal);
> setOperationAction(ISD::XMAC, MVT::Other, Legal);
>
> Then, just set respective instr opcodes in SparcDAGToDAGISel::Select:
>
> case ISD::SRXACC: {
> SDVTList nodeTys = CurDAG->getVTList(MVT::Other);
>
> SDValue Ops[2];
> Ops[0] = N->getOperand(0);
> Ops[1] = N->getOperand(1);
>
> return CurDAG->SelectNodeTo(N, SP::SRXACC, nodeTys, Ops);
> }
> case ISD::XMAC: {
> SDVTList nodeTys = CurDAG->getVTList(MVT::Other);
>
> SDValue Ops[3];
> Ops[0] = N->getOperand(0);
> Ops[1] = N->getOperand(1);
> Ops[2] = N->getOperand(2);
>
> return CurDAG->SelectNodeTo(N, SP::XMAC, nodeTys, Ops);
> }
> case ISD::LRXACC: {
> SDVTList nodeTys = CurDAG->getVTList(MVT::Other, MVT::i32);
> SDValue Ops[1];
> Ops[0] = N->getOperand(0);
> return CurDAG->SelectNodeTo(N, SP::LRXACC, nodeTys, Ops);
> }
>
> They declared as:
> def XMAC : F3_1<2, 0b111111,
> (outs),
> (ins IntRegs:$rs1, IntRegs:$rs2),
> "xmac $rs1, $rs2, %xacc",
> []>;
>
> let rs1 = 0, rd = 1, Uses=[XACC] in
> def LRXACC : F3_1<2, 0b101110,
> (outs IntRegs:$rd), (ins),
> "lrxacc %xacc, $rd", []>;
>
> let rd = 0, Defs=[XACC] in
> def SRXACC : F3_1<2, 0b011101,
> (outs), (ins IntRegs:$rs1),
> "srxacc $rs1, %xacc", []>;
>
> While my register is declared as:
> def XACC : Ri<88, "XACC">, DwarfRegNum<[88]>;
>
> Please, note:
> My problem is of self-educational and investigative nature.
> This instruction srxacc and register xacc are not real.
> Produced code aren't supposed to work anywhere.
> I just need llc to be able to output assembly file.
> Thanks for your insights.
>
>
> 2014-09-01 18:26 GMT+04:00 Sam Parker <S.Parker3 at lboro.ac.uk>:
>
>> Hi,
>> I'm not sure. But in your lowered DAG the chain nodes are the first
>> operands for you custom nodes, however for the other nodes the chain is
the
>> last operand. I seem to remember that during targetlowering the chain
is
>> the first operand and then it seems to switch over after ISelDAG, this
>> confused me and may have something to do with the issue that you are
>> seeing. I really don't know much about scheduling, do you want to
post your
>> instruction definitions again to see if someone else has some ideas,.
>>
>> cheers,
>> sam
>>
>> Sam Parker
>> Research Student
>> Electronic System Design Group
>> School of Electronic, Electrical and Systems Engineering
>> Loughborough University
>> UK
>>
>> On 01/09/14 14:35, Dmitri Kovalenko wrote:
>>
>> Before I wrote here, I tried both ways you decsribed, but none of
>> them has worked out for me.
>> With yours sugesstions I was able to move a bit further with the first
>> approach (when we don't create regclass and just hard-code it in
.td)
>>
>> But I still receive strange errors. I received DAG which I happy with
>> (DAG here: http://goo.gl/62tpkk), but everything goes broken on
>> scheduling.
>>
>> I had to chain mine nodes, because otherwise nodes xmac and srxacc got
>> removed on first combine. But since they are chained, they have
MVT::Other
>> return type, and that causes strange crash inside func GetCostFor in
>> ScheduleDAGRRList.cpp:
>>
>> Def RegClass = TLI->getRepRegClassFor(VT)->getID();
>> When VT is MVT::Other it returns 0x0, what results crash.
>>
>> It got me confused, because reading documentation on CodeGen gave me
an
>> idea, that chain edges are control flow edges, not data edges. So I
don't
>> understand why scheduler tries to assign some register to it.
>>
>> I'm struggling with this problem way to long for now, and I very
>> appreciate yours help, Sam.
>>
>>
>>
>> 2014-09-01 1:50 GMT+04:00 Sam Parker <S.Parker3 at lboro.ac.uk>:
>>
>>> Hi,
>>>
>>> Yes, that's what I would do. If you want LLVM and the register
allocator
>>> to also know that the instruction explicitly defines the register,
I would
>>> designate the register into it's own register class and have
your
>>> instruction write to that class (and there will be only a single
option for
>>> RA).
>>>
>>> cheers,
>>> Sam
>>>
>>> Sam Parker
>>> Research Student
>>> Electronic Systems Design Group
>>> Loughborough University
>>> UK
>>>
>>> ________________________________________
>>> From: Dmitri Kovalenko [dmitri.a.kovalenko at gmail.com]
>>> Sent: 31 August 2014 21:53
>>> To: Sam Parker
>>> Cc: llvmdev at cs.uiuc.edu
>>> Subject: Re: [LLVMdev] understanding DAG: node creation
>>>
>>> Sam, thanks for your answer.
>>> That's a great suggestion.
>>>
>>> And excuse me for maybe dilettante question:
>>> To hard-code use of the global register means to hard-code it in
the
>>> 'asm string' argument of the instruction definition in the
.td file?
>>>
>>>
>>> 2014-09-01 0:44 GMT+04:00 Sam Parker <S.Parker3 at
lboro.ac.uk<mailto:
>>> S.Parker3 at lboro.ac.uk>>:
>>> Hi Dmitri,
>>>
>>> If you have such a simple intrinsic which operates on a single
>>> register, just lower the intrinsic to a target specific node which
is only
>>> implemented by a single instruction. Like you were doing before and
by
>>> using a chain operand. Hard code the instruction to use and define
the
>>> global register and only pass the instruction the actual variable
argument.
>>>
>>> Hope that helps,
>>> Sam
>>>
>>> Sam Parker
>>> Research Student
>>> Electronic Systems Design Group
>>> School of Electronic, Electrical and Systems Engineering
>>> Loughborough University
>>>
>>> ----- Reply message -----
>>> From: "Dmitri Kovalenko" <dmitri.a.kovalenko at
gmail.com<mailto:
>>> dmitri.a.kovalenko at gmail.com>>
>>> To: <llvmdev at cs.uiuc.edu<mailto:llvmdev at
cs.uiuc.edu>>
>>> Subject: [LLVMdev] understanding DAG: node creation
>>> Date: Sat, Aug 30, 2014 22:18
>>>
>>>
>>> I have an intrinsic and it must be lowered to instruction, which
works
>>> with fixed register.
>>> So, it takes contents of this register and another argument as
input.
>>> After execution, the result of the instruction is placed into that
same
>>> fixed register.
>>>
>>> What should I do in SelectionDAGBuilder::visitIntrinicCall to
describe
>>> such behaviour for a SDNode?
>>>
>>> Thank you for the ideas and insights.
>>>
>>> --
>>> Sincerely,
>>> Dmitri Kovalenko
>>>
>>>
>>>
>>> --
>>> Sincerely,
>>> Dmitri Kovalenko
>>>
>>
>>
>>
>> --
>> Sincerely,
>> Dmitri Kovalenko
>>
>>
>>
>
>
> --
> Sincerely,
> Dmitri Kovalenko
>
>
>
--
Sincerely,
Dmitri Kovalenko
--
Sincerely,
Dmitri Kovalenko
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.cs.uiuc.edu/pipermail/llvmdev/attachments/20140902/7bf3b7e8/attachment.html>
------------------------------
_______________________________________________
LLVMdev mailing list
LLVMdev at cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
End of LLVMdev Digest, Vol 123, Issue 3
***************************************
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20140901/a54779b3/attachment.html>