microsoft / llvm Goto Github PK
View Code? Open in Web Editor NEWFork of the LLVM Compiler Infrastructure
Home Page: http://llvm.org
License: Other
Fork of the LLVM Compiler Infrastructure
Home Page: http://llvm.org
License: Other
The LLVM Compiler Infrastructure ================================ This directory and its subdirectories contain source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and runtime environments. LLVM is open source software. You may freely distribute it under the terms of the license agreement found in LICENSE.txt. Please see the documentation provided in docs/ for further assistance with LLVM, and in particular docs/GettingStarted.rst for getting started with LLVM and docs/README.txt for an overview of LLVM's documentation setup. If you are writing a package for LLVM, see docs/Packaging.rst for our suggestions.
We are sign-extending the result of ICmp and FCmp from i1 to i32 instead of zero-extending it. Because of that we generate -1 instead of 1 for true results. That causes bad codegen in a couple of methods in Roslyn.
We need an actual high level LLVM nop or other type of LLVM intrinsic for telling LLVM that we need the debug info attached to the instruction to make it through to when the object file is written. We currently insert an inline asm instruction, which isn't exactly the right thing to do and is architecture dependent. We need something in LLVM that we can use that will be architecture independent and will either convert to a nop when we lower or will pass its debug information on to any following instructions that don't have debug info.
I happened to be stepping through the pass execution and noticed that the GC intrinsics lowering was still scanning the IR in LowerIntrinsics::PerformDefaultLowering
. We don't need this in LLILC with the CoreCLR strategy and we should avoid it and save a bit of TP.
Looks like we need to set CustomReadBarriers
and CustomWriteBarriers
true or something similar for the Strategy to prevent this.
However, there's a comment in GCStrategy.h
that puzzles me -- it says if the strategy specifies UseStatepoints
(which we do for CoreCLR strategy) then all the other options should be defaults. Presumably it meant to say that using gc.root
and related does not make sense as roots are not explicitly identified this way with statepoints. What happens for read/write barriers would appear to be an orthogonal issue.
Similar to #22 but when we probe the stack in the prolog some extra care is needed since it's possible R10 or R11 is live.
CoreCLR's GCTables require call-site size (the length of the call instruction) to be reported for each GC-safepoint. This information is not available in LLVM's stackmap so add it.
Sanjoy Das recommended that this can be recorded correctly (in light of relocations) by using two labels before/after the call-instruction and computing their difference (as an MC-expression).
The inline stack probe needed for the CoreCLR environment on windows is incomplete, and doesn't actually probe the stack. Implement the necessary code.
Currently we generate the following code leading to the post-pinvoke check for GC:
CMP32mi8 %RCX<kill>, 1, %noreg, 0, %noreg, 0, %EFLAGS<imp-def>; mem:LD4[bitcast (i64* @CaptureThreadGlobal to i32*)]
%EDX<def> = COPY %EFLAGS
MOV32mr %RBP, 1, %noreg, -92, %noreg, %EDX<kill>; mem:ST4[FixedStack12]
JE_1 <BB#8>, %EFLAGS<imp-use>
We should be able to avoid the flag spill by passing the flag value to the pause, instead of the result of the flag compare.
github's fork makes it easy to compare and upstream patches. there is an option at https://support.github.com/request/fork to attach this repo as a fork of https://github.com/llvm/llvm-project
Statepoint insertion adds explicit gc.relocate intrinsic calls to reflect retrieving the updated value of a GC pointer across a statepoint. When the statepoint is an invoke that may throw, gc.relocate calls are (currently) needed on both the normal-return path and on the exception path. The current code handles both cases, but only handles the exception path for landingpad-style EH. We'll need to update that to handle funclet-style EH (catchpad/cleanuppad) EH as well.
See e.g. this TODO.
We hit an issue with 8cec2f2 introducing an InvokeStateMap
and looking up InvokeInst
keys in lowerInvokable
from the CallLoweringInfo
parameter, which causes trouble for LLILC since the call to lowerInvokable
that statepoints (and patchpoints) use doesn't attach the CallSite
to the CallLoweringInfo
.
The two means of creating CallLoweringInfo
s (i.e. with and without the CallSite
) have existed for as long as CallLoweringInfo
has. The EH state map needs to use InvokeInst
s as keys now because there are no longer EndPads and so it can't just use the unwind destination like it did previously. The InvokeInst
is needed in SelectionDAGBuilder::lowerInvokable
, which is a private helper method. It has two callers, one of which is for statepoints/patchpoints and the other of which always passes a CallLoweringInfo
with a CallSite
. To me, it makes more sense to just add the InvokeInst
as a parameter to the helper, to avoid upsetting expectations in the call lowering code about what it means when a CallLoweringInfo
has a CallSite
attached to it and to avoid expanding CallLoweringInfo
to include EH state map info that's only relevant for funclet EH.
Since the problem only arises with the combination of statepoint invokes and funclet EH, there won't be a good way to add a lit test demonstrating the issue (which should be included when this change is upstreamed) until #105 has been implemented and upstreamed; statepoint invokes can't be lowered without it. So this issue depends on that one.
Low level expansions need to set physreg liveness properties. Machine verifier can check this.
We should verify we're doing this right for things like the chkstk expansion
File llvm/include/llvm/ADT/SmallBitVector.h has the following code:
template<bool AddBits, bool InvertMask>
void applyMask(const uint32_t *Mask, unsigned MaskWords) {
if (NumBaseBits == 64 && MaskWords >= 2) {
uint64_t M = Mask[0] | (uint64_t(Mask[1]) << 32);
if (InvertMask) M = ~M;
if (AddBits) setSmallBits(getSmallBits() | M);
else setSmallBits(getSmallBits() & ~M);
} else {
uint32_t M = Mask[0];
if (InvertMask) M = ~M;
if (AddBits) setSmallBits(getSmallBits() | M);
else setSmallBits(getSmallBits() & ~M);
}
}
When compiled for a 64 bit target the Microsoft C++ compiler emits
a warning:
.../SmallBitVector.h(565): warning C4319: '~': zero extending 'uint32_t' to 'uintptr_t' of greater size
The line referred to is the one containing the last occurrence of "~M" in the method.
The correct way of avoiding this method depends on the desired semantics of the
applyMask method. This applyMask method is in the SmallBitVector class which
is a specialization of the BitVectorClass. SmallBitVector is supposed to have the same
semantics as BitVectorClass but be more efficient for small bitvectors that will fit
within a pointer-sized word.
If compiling the above for a 32 bit target the warning is not given because then
uintptr_t and uint32_t are the same size.
If compiling for a 64 bit target the code giving the warning can only be executed
if the number of mask words given is 1, because in this case NumBaseBits will
be 64. Since the mask words are 32 bits, this is a case where the mask
words do not cover the bitvector.
So what is the correct semantics when the mask does not cover the bitvector?
One possible interpretation would be that the mask is zero-extended to
the length of the bitvector before being applied. However a reading of the
source code of BitVector shows that this is not the case. In the BitVector
implementation the applyMask operation only affects the part of the
BitVector that is covered by the mask. The remainder of the BitVector
is unaffected. [In current LLVM usage the mask in fact always does
cover the BitVector, except in the bitvector unit tests].
So the correct fix is to replace the offending line with
else setSmallBits(getSmallBits() & ~(uintptr_t )M);
This zero-extends M before the ~ operation occurs, so the
higher-order bits become 1s which then have no effect when &
is applied. So the mask does not affect the result where the
mask is not covering.
An alternate fix I had considered but that would not be correct would be
to change the declaration of the second M to
uintptr_t M = (uintptr_t )Mask[0];
This would give the wrong answer if InvertMask is true, as then
bits not covered by the mask would be affected.
When we try to express a cross-section relative relocation in COFF, LLVM is not including the extra displacement that is involved. For example:
@g3 = constant i32 3;
@t1 = global i64 add(i64 sub(i64 ptrtoint(i32* @g3 to i64), i64 ptrtoint(i64* @t1 to i64) ), i64 4), section ".xxx"
Here the intent is to initialize t1
with the 64 bit relative offset to g3
, but the actual relocation generated does not include the proper offset.
Hi.
I want to know which backend instruction does the llvm support,especially about arm.My biggest doubt is whether llvm-ir can be translated to cortex-m0 instruction at backend section?
best regards.
I am working on some opt transforms that require a monolithic ir file. Compiling the two simple .cpp files to .bc files and linking them with llvm-link causes the MSVC linker to fail with the error below. I do not have this issue if I use a compiled version of clang with MINGW, but for release I need the MSVC version.
Steps to reproduce:
clang.exe -emit-llvm -c one.cpp two.cpp
llvm-link.exe one.bc two.bc -o combined.bc
clang.exe combined.bc -o test3.exe
combined-2b91e8.o : fatal error LNK1243: invalid or corrupt file: COMDAT section 0x17B associated with following section 0x17E clang.exe: error: linker command failed with exit code 1243 (use -v to see invocation)
Note that if I just clang.exe the two bc files out to an executable it works.
one.cpp.txt
two.cpp.txt
two.h.txt
Implement the StackMap v2 proposed on LLVM list:
http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-July/087867.html
Header v2 {
uint8 : Stack Map Version (2)
uint8 : Reserved [3] (0)
uint32 : Constants Offset (bytes)
uint32 : Frame Records Offset (bytes)
uint32 : Frame Registers Offset (bytes)
uint32 : StackMap Records Offset (bytes)
uint32 : Locations Offset (bytes)
uint32 : LiveOuts Offset (bytes)
}
align to 8 bytes
Constants[] {
uint64 : LargeConstant
}
align to 8 bytes
FrameRecord[] {
uint64 : Function Address
uint32 : Function Size
uint32 : Stack Size
uint16 : Flags {
bool : HasFrame
bool : HasVariableSizeAlloca
bool : HasStackRealignment
bool : HasLiveOutInfo
bool : Reserved [12]
}
uint16 : Frame Base Register Dwarf RegNum
uint16 : Num Frame Registers
uint16 : Frame Register Index
uint16 : Num StackMap Records
uint16 : StackMap Record Index
}
align to 4 bytes
FrameRegister[] {
uint16 : Dwarf RegNum
int16 : Offset
uint8 : Size in Bytes
uint8 : Flags {
bool : IsSpilled
bool : Reserved [7]
}
}
align to 8 bytes
StackMapRecord[] {
uint64 : PatchPoint ID
uint32 : Instruction Offset
uint8 : Call size (bytes)
uint8 : Flags {
bool : HasLiveOutInfo
bool : Reserved [7]
}
uint16 : Num Locations
uint16 : Location Index
uint16 : Num LiveOuts
uint16 : LiveOut Index
}
align to 4 bytes
Location[] {
uint8 : Register | Direct | Indirect | Constant | ConstantIndex
uint8 : Reserved (location flags)
uint16 : Dwarf RegNum
int32 : Offset or SmallConstant
}
align to 2 bytes
LiveOuts[] {
uint16 : Dwarf RegNum
uint8 : Reserved
uint8 : Size in Bytes
}
My project needs "-fno-access-control" flag to compile unit tests but unfortunately the clang-cl which is the windows compatible clang compiler for visual studio is not supporting this useful flag.
Will the next releases solve this issue or it's because of windows compatibility and will not change?
Thanks for any comments
Currently the alloca
instruction always allocates in the generic address space (0).
This proposal is to extend the semantics of alloca
instruction to allow allocation in any specified address space.
Proposed Syntax
<result> = alloca [inalloca] <type> [, <ty> <NumElements>] [, align <alignment>] [, addrspace <num>] ; yields type addrspace(num)*:result
Motivation
Managed language clients typically use address space 1 to represent GC-pointers. Some managed clients (CLR, in particular) allow construction of GC pointers to stack locations. For example, MSIL instruction ldloca (ECMA 335, p 370) creates a GC pointer to a stack local.
Creating an addrespace(1)*
pointer to a stack location currently involves two steps: the alloca
, and an addrespacecast
. Managed code transformations (ex: RewriteStatepointsForGC
) do not handle arbitrary address space casting. So, it is desirable to obtain the addrespace(1)*
pointer by construction.
Thanks,
Swaroop.
There are important files that Microsoft projects should all have that are not present in this repository. A pull request has been opened to add the missing file(s). When the pr is merged this issue will be closed automatically.
Microsoft teams can learn more about this effort and share feedback within the open source guidance available internally.
Codegen for callee-save register spilling is currently pretty crude: when lowering GC_TRANSITION_RA, we simply smash the register mask with a new mask that indicates that none of the GPRs that would otherwise have been saved are actually saved, which forces spill/restore generation later on down the road. It would be better to instead have the GC strategy inform the RewriteStatepoints pass that all GC pointers that are live across a GC transition must be spilled.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.