i test clang and compile a simple C file including struct asigning.when I see the LLVM code ,there is llvm.memcpy.p0i8.p0i8.i64 ,where is from ? I not see the defination only see its declare as a fucntion.
It is a LLVM intrinsic function. As per the language reference:
LLVM provides intrinsics for a few important standard C library
functions. These intrinsics allow source-language front-ends to pass
information about the alignment of the pointer arguments to the code
generator, providing opportunity for more efficient code generation.
The llvm.memcpy intrinsic specifically:
The ‘llvm.memcpy.*’ intrinsics copy a block of memory from the source
location to the destination location.
Note that, unlike the standard libc function, the llvm.memcpy.*
intrinsics do not return a value, takes extra isvolatile arguments and
the pointers can be in specified address spaces.
Related
I want to make target independent IR with LLVM.
clang -emit-llvm -S source.c -o source.ll
in source.ll
target datalayout = "e-m:e-i64:..."
target triple = "x86_64-pc-linux-gnu"
...
LLVM IR is said to be Target-independent, but the properties of the target are specified in the actual IR file.
How can I create an LLVM IR without this Target property?
Short answer: you cannot
Long answer: target-neutrality is the property of input language, not the LLVM IR. While in theory it is possible to make more or less target-neutral LLVM IR for some inputs it is not possible for C/C++ inputs. I will only mention few things that prevents us from having such LLVM IR:
Preprocessor. Target-specific #ifdef clauses obviously make resulting IR target-specific
Pointer sizes. Think about expressions like sizeof(void*). These are target-dependent compile-time constants (yes, there are ways to defer calculation of these constants later on, but this is not something frontends are prepared to deal with, this also hinders many optimizations)
Struct layout. Partly it depends on 2. (think about struct { int foo; void* bar; }
Various ABI-related things like necessary support steps for argument / result passing, etc.
I will not mention target-specific things like vectors, builtins for target-specific instructions sets, etc.
I've seen some Rust codebases use the #[repr(C)] macro (is that what it's called?), however, I couldn't find much information about it but that it sets the type layout in memory to the same layout as 'C's.
Here's what I would like to know: is this a preprocessor directive restricted to the compiler and not the language itself (even though there aren't any other compiler front-ends for Rust), and why does Rust even have a memory layout different than that of Cs? (it's just that I've never had to do this in another language).
Here's a nice situation to demonstrate what I meant: if someone creates another compiler for Rust, are they required to implement this macro, or is it a compiler specific thing?
#[repr(C)] is not a preprocessor directive, since Rust doesn't use a preprocessor 1. It is an attribute. Rust doesn't have a complete specification, but the repr attribute is mentioned in the Rust reference, so it is absolutely a part of the language. Implementation-wise, attributes are parsed the same way all other Rust code is, and are stored in the same AST. Rust has no "attribute pass": attributes are an actual part of the language. If someone else were to implement a Rust compiler, they would need to implement #[repr(C)].
Furthermore, #[repr(C)] can't be implemented without some compiler magic. In the absence of a #[repr(...)], Rust compilers are free to arrange the fields of a struct/enum however they want to (and they do take advantage of this for optimization purposes!).
Rust does have a good reason for using it's own memory layout. If compilers aren't tied to how a struct is written in the source code, they can do optimisations like not storing struct fields that are never read from, reordering fields for better performance, enum tag pooling2, and using spare bits throughout NonZero*s in the struct to store data (the last one isn't happening yet, but might in the future). But the main reason is that Rust has things that just don't make sense in C. For instance, Rust has zero-sized types (like () and [i8; 0]) which can't exist in C, trait vtables, enums with fields, generic types, all of which cause problems when trying to translate them to C.
1 Okay, you could use the C preprocessor with Rust if you really wanted to. Please don't.
2 For example, enum Food { Apple, Pizza(Topping) } enum Topping { Pineapple, Mushroom, Garlic } can be stored in just 1 byte since there are only 4 possible Food values that can be created.
What is this?
It is not a macro it is an attribute.
The book has a good chapter on what macros are and it mentions that there are "Attribute-like macros":
The term macro refers to a family of features in Rust: declarative macros with macro_rules! and three kinds of procedural macros:
Custom #[derive] macros that specify code added with the derive attribute used on structs and enums
Attribute-like macros that define custom attributes usable on any item
Function-like macros that look like function calls but operate on the tokens specified as their argument
Attribute-like macros are what you could use like attributes. For example:
#[route(GET, "/")]
fn index() {}
It does look like the repr attribute doesn't it 😃
So what is an attribute then?
Luckily Rust has great resources like rust-by-example which includes:
An attribute is metadata applied to some module, crate or item. This metadata can be used to/for:
conditional compilation of code
set crate name, version and type (binary or library)
disable lints (warnings)
enable compiler features (macros, glob imports, etc.)
link to a foreign library
mark functions as unit tests
mark functions that will be part of a benchmark
The rust reference is also something you usually look at when you need to know something more in depth. (chapter for attributes)
To the compiler authors out there:
If you were to write a rust compiler, and wanted to support things like the standard library or other crates then you would 100% need to implement these. Because the libraries use these and need them.
Otherwise I guess you could come up with a subset of rust that your compiler supports. But then most people wouldn't use it..
Why does rust not just use the C layout?
The nomicon explains why rust needs to be able to reorder fields of structs for example. For reasons of saving space and being more efficient. It is related to, among other things, generics and monomorphization. In repr(C) fields of structs must be in the same order as the definition.
The C representation is designed for dual purposes. One purpose is for creating types that are interoperable with the C Language. The second purpose is to create types that you can soundly perform operations on that rely on data layout such as reinterpreting values as a different type.
I have a question..
In the IR level of LLVM, is there any method exist to distinguish between static_cast and dynamic_cast ?
If yes, how to check it using commands in the IR level ?
I know that, in the clang level, there are some method already exist as below.
-http://clang.llvm.org/doxygen/classclang_1_1CXXNamedCastExpr.html
Could you give me a valuable guide ?
Thank you very much :)
No. LLVM IR does not represent static_cast, dynamic_cast, or any such C++ source-level construct. Even ABI-specific hints may not always be present, for example Itanium under some circumstances does not emit calls to the runtime function.
I run Lua on a CPU without dedicated floating point HW, depending on SW emulation.
From luaopt.h I can see that some macros are set to double, but it does not clearly state when floats are used and its a little hard to track it.
If my script does simple stuff like:
a=0
a=a+1
for...
Would that involve a floating point operations at any level?
If no that's fine, but what is then the benefit to change macros to long?
(I tried of course but did not work....)
All numeric operations in Lua are performed (according to the default configuration) in floating point. There is no distinction made between floating point and integer, all values are simply numbers.
The actual C type used to store a Lua number is set in luaconf.h, and it is both allowed and even practical to change that to a suitable integral type. You start by changing LUA_NUMBER from double to int, long, or perhaps ptrdiff_t. Then you will find you need to tweak the related macros that control the conversions between strings and numbers. And, of course, you will likely need to eliminate most or all of the base math library since math.sin() and its friends and neighbors are not particularly useful over integers.
The result will be a Lua interpreter where all numbers are integers. The language will still allow you to type 3.14, but it will be stored as 3. Your code will likely not be completely portable to a Lua interpreter built with the standard configuration since a huge amount of Lua code casually assumes that floating point arithmetic is permitted, and remember that your compiled byte code will definitely not be compatible since byte code will store numbers as LUA_NUMBER.
There is LNUM patch (used, for example, by OpenWrt project which relies heavily on Lua for providing Web UI on hardware without FPU) that allows dual integer/floating point representation of numbers in Lua with conversions happening behind the scenes when required. With it most integer computations will be performed without resorting to FPU. Unfortunately, it's only applicable to Lua 5.1; 5.2 is not supported.
Is it possible to automatically generate interface units from C header files? In particular, I want to wrap the HDF5 library, and it would be great if I could avoid writing the interface unit manually.
The free pascal includes the H2PAS tool.
h2pas attempts to convert a C header file to a pascal unit. it can
handle most C constructs that one finds in a C header file, and
attempts to translate them to their pascal counterparts.
Bob Swart (Dr Bob) has a utility which will convert a lot of header files (although there's usually some manual work involved as well) called HeaderConvert. I've never compared it to the tool #RRUZ links, but it's another option.
Project JEDI has one as well; I've never tested it. You can find it here.
In general fully automated translating of C headers to something else (that isn't an effective superset of the needed C functionality) is hard to impossible.
This because due to macros one can't see how to translate them. Macros often only get their meaning from context. Example
#define uglymacro 1,2,3,4
but also (and this one is more common):
SCARYAPIMACRO void func(int c);
SCARYAPIMACRO is then often a macro that tests OS defines to select the right calling convention for the right OS/architecture.
Still, that doesn't mean that the tools are not real timesavers. But the result is more semiautomatic, I've the most and best experience with h2pas.
I've translated a lot of Windows headers (including FPC's commctrl which has a sendmessage macro every few lines).
What I usually do is craft a small pascal program that scans the source linebased and uses heuristics to split it into parts that are mostly homogeneous (all structs or constants,macros, procedure declaration etc). Then I look at the source and often do some global substitutes.
Only then I run it through the translator, the process is often iterative (refine separation, do global substitutions, try to translate, if it fails, try again etc).
The process unfortunately does require a good grasp of C, pragma stuff included.
You can download HDF5 API header Delphi translations, Delphi XE2 HDF5 table test program with source code and somewhat modified hdf5dll from my page:
http://www.astro.ff.vu.lt/index.php?option=com_content&task=view&id=46&Itemid=63