ãã®åé¡ã¯ãLLVMã®ãã°ã®ããã«ã httpsïŒ//github.com/rust-lang/rust/pull/54639ã§å°å
¥ããã-Zmutable-alias=no
ããã©ã«ãã®åãæ¶ãã远跡ããŸãã cc @nagisa
ïŒæ¢èŠæïŒ ïŒ
ç§ã¯ãŸã æ ¹æ¬çãªåé¡ã解æããããã«åãçµãã§ããŸãã èå³æ·±ããã±ããã¯https://github.com/rust-lang/rust/issues/54462ã§ãã
@nagisaã®æå°éã®è€è£œã䜿çšããïŒ
å®å
šã§ãªãã³ãŒãã®ãªãæå°åããããã¹ãã±ãŒã¹ïŒå¿
ã1ã€ã®codegenãŠãããã§ã³ã³ãã€ã«ããŠãã ããïŒïŒïŒ
fn linidx(row: usize, col: usize) -> usize {
row * 1 + col * 3
}
fn swappy() -> [f32; 12] {
let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0];
for i in 0..2 {
for j in i+1..3 {
if mat[linidx(j, 3)] > mat[linidx(i, 3)] {
for k in 0..4 {
let (x, rest) = mat.split_at_mut(linidx(i, k) + 1);
let a = x.last_mut().unwrap();
let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
::std::mem::swap(a, b);
}
}
}
}
mat
}
fn main() {
let mat = swappy();
assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat);
}
LLVMã®æé©åãã¹ãäºçåããŠããšã©ãŒã®åå ãšãªã£ãŠãããã¹ãèŠã€ããããšãã§ããŸããã
ãã®ã³ãã³ããå®è¡ãããšãå®è¡å¯èœã«ãªããŸãïŒ bug.rs
ããè€è£œãä¿åãããã¡ã€ã«ã®ååã«çœ®ãæããŸãïŒã
rustc -Z no-parallel-llvm -C codegen-units=1 -O -Z mutable-noalias=yes -C llvm-args=-opt-bisect-limit=2260 bug.rs
ãã®ã³ãã³ããå®è¡ããŠããéãå®è¡å¯èœãã¡ã€ã«ãå£ããŸãïŒ `assert_eq``ã¯å€±æããŸãïŒïŒ
rustc -Z no-parallel-llvm -C codegen-units=1 -O -Z mutable-noalias=yes -C llvm-args=-opt-bisect-limit=2261 bug.rs
ãã®ãã¡ã€ã«ã®å Žåãæé©å2261
ã¯Global Value Numbering on function (_ZN3bug6swappy17hdcc51d0e284ea38bE)
察å¿ããŸã
LLVMãªããžã§ã³ãäºçåããïŒllvmlabäºçåç·ã䜿çšïŒãšãr305936-r305938ãããããr305938ã«çµã蟌ãŸããŸãã
[BasicAA]ãã©ãŒã«ããã¯ã«PartialAliasã®ä»£ããã«MayAliasã䜿çšããŸãã
ããã¯2017幎6æããã®ããªãå€ãå€æŽã§ããããšã«æ³šæããŠãã ããã
ç·šéïŒã³ãããã®èª¬æãèŠããšããã°ã¯ãã以åã«ååšããŠããå¯èœæ§ããããŸãããBasicAAã«ãã£ãŠãã¹ã¯ãããåŸã®ãšã€ãªã¢ã¹ãã¹ãå®è¡ãããªãããã«ãªã£ãŠããŸãããããã³ãããã®ä¿®æ£ã§ãã ãã®å Žåãã³ã³ãã€ã©ãåãããŒã¹ã¢ãã¬ã¹ãæã£ãŠããããšã¯ç¥ã£ãŠãããããªãã»ããã¯ç¥ããªãã getelementptr
åœä»€ã®ãã¢éã®ãšã€ãªã¢ã·ã³ã°ããã§ãã¯ããå¿
èŠããããŸãã
Edit2ïŒãŸããLLVMãªãã·ã§ã³ãšããŠ-enable-scoped-noalias=false
ãæž¡ããšã誀ã³ã³ãã€ã«ãé²ãããšãã§ããŸãã ïŒããã«ãããnoaliasã®åŠçãå®å
šã«ç¡å¹ã«ãªããããããã¯é©ãã¹ãããšã§ã¯ãããŸãããã念ã®ããã«âŠïŒ
GVN以åã®IRãèŠããšãLLVMãšã€ãªã¢ã·ã³ã°ã¢ãããŒã·ã§ã³ãã©ã®ããã«æ©èœãããã«ã€ããŠã®ç§ã®ç解ãæ£ãããã©ããã«ãã£ãŠã¯ãããã§ã®æ ¹æ¬çãªåå ãã«ãŒãå±éã«ããå¯èœæ§ãããããã«æããŸãã
次ã®ãããªã³ãŒããèããŠã¿ãŸããã
int *a, *b;
for (int i = 0; i < 4; i++) {
a[i & 1] = b[i & 1];
}
ããã§ã a[i & 1]
ãšb[i & 1]
ã¯åäžã®å埩å
ã§ãšã€ãªã¢ã¹ããŸãããã a
ãšb
ã¯äžè¬ã«ãšã€ãªã¢ã¹ããå¯èœæ§ããããŸãã
LLVM IRã§ã¯ãããã¯æ¬¡ã®ããã«ãªããŸãã
define void @test(i32* %addr1, i32* %addr2) {
start:
br label %body
body:
%i = phi i32 [ 0, %start ], [ %i2, %body ]
%j = and i32 %i, 1
%addr1i = getelementptr inbounds i32, i32* %addr1, i32 %j
%addr2i = getelementptr inbounds i32, i32* %addr2, i32 %j
%x = load i32, i32* %addr1i, !alias.scope !2
store i32 %x, i32* %addr2i, !noalias !2
%i2 = add i32 %i, 1
%cmp = icmp slt i32 %i2, 4
br i1 %cmp, label %body, label %end
end:
ret void
}
!0 = !{!0}
!1 = !{!1, !0}
!2 = !{!1}
ããã-loop-unroll
ãããšã次ã®ããã«ãªããŸãã
define void @test(i32* %addr1, i32* %addr2) {
start:
br label %body
body: ; preds = %start
%x = load i32, i32* %addr1, !alias.scope !0
store i32 %x, i32* %addr2, !noalias !0
%addr1i.1 = getelementptr inbounds i32, i32* %addr1, i32 1
%addr2i.1 = getelementptr inbounds i32, i32* %addr2, i32 1
%x.1 = load i32, i32* %addr1i.1, !alias.scope !0
store i32 %x.1, i32* %addr2i.1, !noalias !0
%x.2 = load i32, i32* %addr1, !alias.scope !0
store i32 %x.2, i32* %addr2, !noalias !0
%addr1i.3 = getelementptr inbounds i32, i32* %addr1, i32 1
%addr2i.3 = getelementptr inbounds i32, i32* %addr2, i32 1
%x.3 = load i32, i32* %addr1i.3, !alias.scope !0
store i32 %x.3, i32* %addr2i.3, !noalias !0
ret void
}
!0 = !{!1}
!1 = distinct !{!1, !2}
!2 = distinct !{!2}
ã«ãŒãã®4ã€ã®ã³ããŒãã¹ãŠããåããšã€ãªã¢ã·ã³ã°ãã¡ã€ã³ã§ãšã€ãªã¢ã·ã³ã°ã¡ã¿ããŒã¿ã䜿çšããæ¹æ³ã«æ³šæããŠãã ããã 1åã®å埩ã§ããšã€ãªã¢ã¹ã«ãªãã®ã§ã¯ãªããé¢æ°å šäœã§ããšã€ãªã¢ã¹ã«ãªããŸãã
æåŸã«ã -scoped-noalias -gvn
ã¯æ¬¡ã®ããã«ãªããŸãã
define void @test(i32* %addr1, i32* %addr2) {
start:
%x = load i32, i32* %addr1, !alias.scope !0
store i32 %x, i32* %addr2, !noalias !0
%addr1i.1 = getelementptr inbounds i32, i32* %addr1, i32 1
%addr2i.1 = getelementptr inbounds i32, i32* %addr2, i32 1
%x.1 = load i32, i32* %addr1i.1, !alias.scope !0
store i32 %x.1, i32* %addr2i.1, !noalias !0
store i32 %x, i32* %addr2, !noalias !0
store i32 %x.1, i32* %addr2i.1, !noalias !0
ret void
}
!0 = !{!1}
!1 = distinct !{!1, !2}
!2 = distinct !{!2}
ãŸãã a = b + 1
å Žåãããã¯èª€ã£ãçµæã«ãªããŸãã
次ã®ã³ãŒãã䜿çšããŠãCãããã®åé¡ãåçŸããããšãã§ããŸãã
#include "stdio.h"
void copy(int * restrict to, int * restrict from) {
*to = *from;
}
void test(int *a, int *b) {
for (int i = 0; i < 4; i++) {
copy(&b[i & 1], &a[i & 1]);
}
}
int main() {
int ary[] = {0, 1, 2};
test(&ary[1], &ary[0]);
printf("%d %d %d\n", ary[0], ary[1], ary[2]);
return 1;
}
ã¯ã©ã³6.0ã§ã¯ãããå°å·ã2 2 2
ã§-O0
ãš1 2 2
ã§-O3
ã ãã®ã³ãŒããCã®restrict
ã»ãã³ãã£ã¯ã¹ã®äžã§åæ³ãã©ããã¯ããããŸããããLLVMã®ããå³å¯ãªnoalias
ã»ãã³ãã£ã¯ã¹ã®äžã§ã¯åæ³ã§ããã¯ãã§ãã
ç§ã¯ãããåçŽãªCãã¹ãã±ãŒã¹ã«æžãããŸããïŒ-O3ãš-O0ã§ã³ã³ãã€ã«ããåºåãæ¯èŒããŸãïŒïŒ
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
__attribute__((always_inline))
static inline void copy(int *restrict a, int *restrict b) {
assert(a != b);
*b = *a;
*a = 7;
}
__attribute__((noinline))
void floppy(int mat[static 2], size_t idxs[static 3]) {
for (int i = 0; i < 3; i++) {
copy(&mat[i%2], &mat[idxs[i]]);
}
}
int main() {
int mat[3] = {10, 20};
size_t idxs[3] = {1, 0, 1};
floppy(mat, idxs);
printf("%d %d\n", mat[0], mat[1]);
}
restrict
ãåé€ãããšãCã¯noalias
ã«çžåœããåäœã¯æ£ããããšã«æ³šæããŠãã ããã ããã§ãã assert(a != b)
åæ Œãã restrict
åŒã³åºãããã«UBãçºçããªãããšã蚌æããŸãã
äœãèµ·ãã£ãŠããã®ã§ããïŒ
for (int i = 0; i < 3; i++) {
mat[idxs[i]] = mat[i%2]; mat[i%2] = 7;
}
mat[idxs[0]] = mat[0]; mat[0] = 7; /* from copy(&mat[0%2], &mat[idxs[0]]) */
mat[idxs[1]] = mat[1]; mat[1] = 7; /* from copy(&mat[1%2], &mat[idxs[1]]) */
mat[idxs[2]] = mat[0]; mat[0] = 7; /* from copy(&mat[2%2], &mat[idxs[2]]) */
mat[0]
ã¯mat[idxs[1]]
ãŸãã¯mat[1]
ã§ãšã€ãªã¢ã¹ã§ããªããšèããŠããŸãããšã«ãŽã¯ã mat[0] = 7;
ãšmat[idxs[2]] = mat[0];
éã§å€æŽã§ããŸããããšã«ãŽmat[idxs[2]] = 7;
ã«æé©åããããã®ã°ããŒãã«å€ã®çªå·ä»ãããã ãã idxs[1] == 0
ã§ããããã mat[0]
ã¯mat[idxs[1]]
ãšãšã€ãªã¢ã¹ããŸãã ãŸãã &mat[idxs[1]]
ãcopy
ã«æž¡ããã2åç®ã®å埩ã§ã¯ãä»ã®åŒæ°ã¯&mat[1]
ã§ãããããããããªããšã¯çŽæããŸãã
ãããšãããã¯copy
ãã€ã³ã©ã€ã³åãããæ¹æ³ãšé¢ä¿ããããŸãã noalias
é¢æ°å±æ§ã¯ã次ã®ãããªããŒãããã³ã¹ãã¢åœä»€ã§!alias.scope
ããã³!noalias
ã¡ã¿ããŒã¿ã«å€æãããŸãã
%8 = load i32, i32* %0, align 4, !tbaa !8, !alias.scope !10, !noalias !13
store i32 %8, i32* %7, align 4, !tbaa !8, !alias.scope !13, !noalias !10
store i32 7, i32* %0, align 4, !tbaa !8, !alias.scope !10, !noalias !13
éåžžãé¢æ°ãè€æ°åã€ã³ã©ã€ã³åãããå Žåãåã³ããŒã¯alias.scopeãšnoaliasã®ç¬èªã®äžæã®IDãååŸããŸããããã¯ãååŒã³åºããnoalias
ïŒ restrict
ïŒCã¬ãã«ïŒãåŒã³åºãããšã«å€ãç°ãªãå ŽåããããŸãã
ãã ãããã®å Žåãæåã«é¢æ°ãã«ãŒãã«ã€ã³ã©ã€ã³åããã次ã«ã«ãŒããå±éããããšãã«ã€ã³ã©ã€ã³åãããã³ãŒããè€è£œãããŸãããã®è€è£œã«ãã£ãŠIDã¯å€æŽãããŸããã ãã®ãããLLVMã¯ãã®ã©ããèããŠããªãa
'ã®ããããã®çŒ¶å¥åb
ãåœã§ãããs'ãçç±a
第äžåã³ç¬¬äžã®é話ãšã€ãªã¢ã¹ãã2çªç®ã®åŒã³åºãããã®b
ã䜿çšããŸãïŒãã¹ãŠ&mat[0]
æããŸãïŒã
é©ãã¹ãããšã«ãGCCãããã誀ã£ãŠã³ã³ãã€ã«ããåºåãç°ãªããŸãã ïŒ-O0ã§ã®clangãšGCCã¯äž¡æ¹ãšã7 10
åºåããŸã; -O3ã§ã®clangã¯7 7
åºåããŸã; -O3ã§ã®GCCã¯10 7
åºåããŸããäœããå°ç¡ãã«ããŠãçµå±UBãè¿œå ããŸãããæ¹æ³ãããããŸãã...
*ãããããå°ãè€éã§ããããã®å Žåã copy
ã¯ãã€ã³ã¿æŒç®ã䜿çšãããäž¡æ¹ã®ãã€ã³ã¿ã«æžã蟌ããããäžçåŒa != b
ãå¿
èŠã§ããã UBã«ãªããŸãã
ãããåã説æãèŠã€ããããã«@nikicãšç«¶äºããããã§ãã 圌ãã®ãã¹ãã±ãŒã¹ã¯å°ãè¯ãã§ã:)
ããã¯æ¬åœã«çŽ æŽãããã¿ã€ãã³ã°ã§ã^^åæã«ã»ãŒåãåæžããããã¹ãã±ãŒã¹ã§åãçµè«ã«éããŸãã:)
ãããä¿®æ£ããã«ã¯ãããããhttps://github.com/llvm-mirror/llvm/blob/54d4881c352796b18bfe7314662a294754e3a752/lib/Transforms/Utils/InlineFunction.cpp#L801ã«æ²¿ã£ãäœããLoopUnrollPassã§å®è¡ããå¿ èŠããããŸãã
ãã®åé¡ã®LLVMãã°ã¬ããŒããhttps://bugs.llvm.org/show_bug.cgi?id=39282ã«éä¿¡ããŸãã
ãããŠãå®å šãæãããã«ããã«èšåããã ãã§ãCãã¹ãã±ãŒã¹ã誀ã£ãŠã³ã³ãã€ã«ãããããããã°ã¬ããŒããGCCã«éä¿¡ããŸããïŒ https ïŒ//gcc.gnu.org/bugzilla/show_bug.cgiïŒid = 87609
ããªã¢ãŒãžïŒãããæ£ããèªãã§ããã°ãLLVMä¿®æ£ãåãå ¥ããããŸããïŒhttps://reviews.llvm.org/D9375ïŒã ãããå®éã«LLVMã«ããŒãžããããšã®æå³ããŸãã¯ããããã€èµ·ãã£ãã®ãã¯ããããŸããã LLVMã®æ¹èšããã»ã¹ã«ç²ŸéããŠãã人ã¯ãåé¡ãä»ä¿®æ£ãããŠãããã©ããïŒããã³ã©ã®ããŒãžã§ã³ãïŒã確èªããå¿ èŠããããŸãã
ããã¯ããŒãžãããŠããããã¬ãã¥ãŒããã»ã¹ã¯å°ãå¥åŠã§ããããOKãã人ã¯ããããããã¬ãã¥ãŒããŸããã
ç§ã¯ãããããããšæã£ãŠããŸãã
é©åºŠã«åŒ·åãªãµãŒããŒïŒ48 HTã³ã¢ã128Gã®RAMïŒã«ã¢ã¯ã»ã¹ã§ãããããã䜿çšããŠãã¹ãŠãæ£ããæ§ç¯ã§ãããšæããŸãã
åäœããããŒã«ãã§ãŒã³ãã§ããããã©ã®ã¯ã¬ãŒããè©Šãããšããå§ãããŸããïŒ
llvmã®ã¢ããã¹ããªãŒã ãã¹ã¿ãŒã§ãã¹ãŠã®ruståºæã®ã³ããããããŒãžãçµããŠãããããããé©çšããŸããã
çµæã®ãã©ã³ãã¯æ¬¡ã®ãšããã§ãïŒ https ïŒ
ããŒã«ãã§ãŒã³ãã³ã³ãã€ã«ããŠè©ŠããŠã¿ãŸããã
ãŸãã https ïŒ
æåã«è©Šãã®ã«é©ããæ¹æ³ã¯ã次ã®ãããªãã®ã§ãã
pub fn adds(a: &mut i32, b: &mut i32) {
*a += *b;
*a += *b;
}
ãããŠãããã次ã®ãããªãã®ã«ã³ã³ãã€ã«ãããããšã確èªããŸãã
example::adds:
mov eax, dword ptr [rsi]
add eax, eax
add dword ptr [rdi], eax
ret
ã§ã¯ãªã
example::adds:
mov eax, dword ptr [rdi]
add eax, dword ptr [rsi]
mov dword ptr [rdi], eax
add eax, dword ptr [rsi]
mov dword ptr [rdi], eax
ret
次ã«ã httpsïŒ //github.com/rust-lang/rust/issues/54462#issue-362850708ã®ã³ãŒãã誀ã£ãŠã³ã³ãã€ã«ãããŠããªãããšã確èªããŸãã
@ jrmuizel ïŒ54639ã«ã¯ãæ°ããã³ã³ãã€ã©ãã¹ããšããŠïŒ54462çšã®@nagisaã®æå°éã®åçŸæ©èœã
AFAIKã¯ããã©ã«ãã®ãã©ã°ïŒ -Zmutable-noalias=yes
ã§ãªãŒããŒã©ã€ãã§ããŸãïŒãå€æŽããã ãã§ãããåè¿°ã®ãã¹ããã¡ã€ã«ãæåã§ã³ã³ãã€ã«ã§ããããããããå«ãããã©ããã¯éèŠã§ã¯ãªããšæããŸãã
ãåç¥ã®ãšãããç§ã¯ãŸã LLVMããã«ãããããšããŠããŸãããçŸæç¹ã§ã¯ãruståºæã®ããããé©çšãããŠãããã©ããã«é¢ä¿ãªãã³ã³ãã€ã«ãšã©ãŒãçºçããŸãïŒã€ãŸããã¢ããã¹ããªãŒã ã®llvmãã¹ã¿ãŒãšãããã倱æããŸãïŒã
In file included from /usr/include/c++/8/cmath:45,
from /opt/rust/src/llvm-project/llvm/include/llvm-c/DataTypes.h:28,
from /opt/rust/src/llvm-project/llvm/include/llvm/Support/DataTypes.h:16,
from /opt/rust/src/llvm-project/llvm/include/llvm/ADT/Hashing.h:47,
from /opt/rust/src/llvm-project/llvm/include/llvm/ADT/ArrayRef.h:12,
from /opt/rust/src/llvm-project/llvm/include/llvm/Transforms/Utils/NoAliasUtils.h:16,
from /opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:13:
/opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp: In function âvoid llvm::cloneNoAliasScopes(llvm::ArrayRef<llvm::MetadataAsValue*>, llvm::DenseMap<llvm::MDN
ode*, llvm::MDNode*>&, llvm::DenseMap<llvm::MetadataAsValue*, llvm::MetadataAsValue*>&, llvm::StringRef, llvm::LLVMContext&)â:
/opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:174:30: error: no matching function for call to âllvm::AliasScopeNode::AliasScopeNode(double)â
llvm::AliasScopeNode SNAN(MD);
^~~~
In file included from /opt/rust/src/llvm-project/llvm/include/llvm/IR/TrackingMDRef.h:16,
from /opt/rust/src/llvm-project/llvm/include/llvm/IR/DebugLoc.h:17,
from /opt/rust/src/llvm-project/llvm/include/llvm/IR/Instruction.h:21,
from /opt/rust/src/llvm-project/llvm/include/llvm/IR/BasicBlock.h:22,
from /opt/rust/src/llvm-project/llvm/include/llvm/IR/Instructions.h:27,
from /opt/rust/src/llvm-project/llvm/include/llvm/Transforms/Utils/NoAliasUtils.h:22,
from /opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:13:
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1446:12: note: candidate: âllvm::AliasScopeNode::AliasScopeNode(const llvm::MDNode*)â
explicit AliasScopeNode(const MDNode *N) : Node(N) {}
^~~~~~~~~~~~~~
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1446:12: note: no known conversion for argument 1 from âdoubleâ to âconst llvm::MDNode*â
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1445:3: note: candidate: âconstexpr llvm::AliasScopeNode::AliasScopeNode()â
AliasScopeNode() = default;
^~~~~~~~~~~~~~
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1445:3: note: candidate expects 0 arguments, 1 provided
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1441:7: note: candidate: âconstexpr llvm::AliasScopeNode::AliasScopeNode(const llvm::AliasScopeNode&)â
class AliasScopeNode {
^~~~~~~~~~~~~~
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1441:7: note: no known conversion for argument 1 from âdoubleâ to âconst llvm::AliasScopeNode&â
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1441:7: note: candidate: âconstexpr llvm::AliasScopeNode::AliasScopeNode(llvm::AliasScopeNode&&)â
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1441:7: note: no known conversion for argument 1 from âdoubleâ to âllvm::AliasScopeNode&&â
/opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:177:31: error: request for member âgetNameâ in â__builtin_nans(((const char*)""))â, which is of non-class ty
pe âdoubleâ
auto ScopeName = SNAN.getName();
^~~~~~~
/opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:187:39: error: request for member âgetDomainâ in â__builtin_nans(((const char*)""))â, which is of non-class
type âdoubleâ
const_cast<MDNode *>(SNAN.getDomain()), Name);
^~~~~~~~~
[ 75%] Building CXX object lib/Target/Hexagon/CMakeFiles/LLVMHexagonCodeGen.dir/RDFCopy.cpp.o
make[2]: *** [lib/Transforms/Utils/CMakeFiles/LLVMTransformUtils.dir/build.make:635: lib/Transforms/Utils/CMakeFiles/LLVMTransformUtils.dir/NoAliasUtils.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
LLVMãã¹ã¿ãŒããã§ã«ããããšåæããŠããªãå¯èœæ§ãããïŒãããã®å€§ãããšLLVMãã¹ã¿ãŒã®ç§»åé床ãèæ ®ãããšçºçããå¯èœæ§ããããŸãïŒãLLVMãã¹ã¿ãŒã®å€ããªããžã§ã³ã«å¯ŸããŠãã«ãããå¿ èŠããããŸããïŒ ããã«ã€ããŠãããã®äœæè ã«pingãéä¿¡ããããšã¯ééããªã䟡å€ããããŸãã
ããã¯ãŸãã«ç§ããã£ãŠããããšã§ããããããã§ãã«ããããå€ããªããžã§ã³ãèŠã€ããããšããŠããŸã:-)
åé¡ã¯llvm / masterã«ããã®ã§ã¯ãªãããããã«ãããšç¢ºä¿¡ããŠããŸãã
ãŸã ããããšäºææ§ã®ããllvm / masterããã®æãå€ãã³ãããã¯https://github.com/llvm/llvm-project/commit/5b99c189b3bfc0faa157f7ca39652c0bb8c315a7ã§ãããããã§ããããã®ã³ã³ãã€ã«ã«å€±æããŸãã
ç§ã¯ç²ããããŠæ æ°ã§ãä»C ++ãç解ããããšã¯ããŠããŸãããææ¥ãããäžåºŠããçŽããŸãã
ãããŸã§ã®éã誰ãããããã®äœæè
ã«é£çµ¡ããŠå©ããæ±ããããšã¯ã§ããŸããïŒ
rustllvmã«ããããé©çšããã«ãïŒå®éã«ãã«ãããåŸïŒRustã§ãã¹ã¿ãŒLLVMãç°¡åã«äœ¿çšã§ãããšã¯æããŸããã AFAIKã¯ãçŸåšãªãªãŒã¹6ã9ã®ã¿ããµããŒãããŠããŸãã
@ mati865æåã«rustã®llvm-9ãã©ãŒã¯ã«ããããé©çšããããšããŸãããããããç°¡åã§ã¯ãããŸããã§ãã...
ãããã¯æããã«llvm / llvm-project @ 82d3ba87d06f9e2abc6e27d8799587d433c56630ã®äžã«ãªããŒã¹ãããŠããŸãã ãã®äžã«é©çšãããšãããã¯ããªãã®ããã«æ§ç¯ãããŸããïŒ
@jrmuizelããããšãç§ã¯ãããè©ŠããŠã¿ãŸãïŒ
ãããŸã§ã®éãç§ã¯rustllvmãllvmãã¹ã¿ãŒã§ãã«ãããããã«ããŸãé©å¿ãããããšãã§ããŸããã
@PaulGrandperrinã«pingã
çŸå®çã«èšãã°ããã®ãããã®ãµã€ãºãèæ ®ããŠããã®ããããããŒãžãããäºå®ã®ã¿ã€ã ã©ã€ã³ãšå šäœçãªå¯èœæ§ã¯ã©ã®ãããã§ããïŒ
@MSxDOSLLVMéçºè ã«èããŠã¿ãŠãã ããã äžè¬ã«ããããã®ãµã€ãºã¯ããããããŒãžãããã®ãèŠãããšããææè ã®æã¿ãããéèŠã§ã¯ãªããšæãã®ã§ã質åããã®ã¯ãLLVMãã©ãã ãããããçå°ããã®ãèŠããããšããããšã§ãã
ãããç§ãèŠãææ°ã®ã¹ããŒã¿ã¹ã§ãïŒ https ïŒ
https://github.com/bytecodealliance/cranelift ~~ https://github.com/bjorn3/rustc_codegen_craneliftãããŸããããšãããæç¹ã§é¢é£æ§ã
@ leeoniya ãoptãã«ãã«craneliftã䜿çšããçæçãªèšç»ã¯ãããŸããã ã¯ã¬ãŒã³ãªããã«ã¯ããããå¯èœã«ããããã«å¿ èŠãªæé©åäœæ¥ããããããããŸããã
ãã®ãªãã·ã§ã³ããªããšãšã€ãªã¢ã·ã³ã°ãçºçããå¯èœæ§ããããšæ³å®ããŠãã³ã³ãã€ã©ãã©ãã»ã©ä¿å®çã§ããããç¥ã£ãŠé©ããã äŸãã°ïŒ
fn baz(s: &mut S) {
if s.y < 10 {
s.x = foo();
}
if s.y < 5 {
s.x = foo();
}
}
&mut
ãä»ããŠæ§é äœã¡ã³ããŒã«ã¢ã¯ã»ã¹ããããã s.x
ãšs.y
ããšã€ãªã¢ã¹å¯èœã§ãããšæ³å®ãã s.y
ã«å¯ŸããŠ1åã§ã¯ãªãã2åã®ã¡ã¢ãªã¢ã¯ã»ã¹ãå¿
èŠã§ãã éåžžã®ããã°ã©ã ã§ã¡ã³ããŒã&mut
ãä»ããŠèªã¿åã/æžã蟌ã¿ãäœåã€ã³ã¿ãŒãªãŒãããå¿
èŠãããããèãããšãããã¯æ¬åœã«æ®å¿µãªããšã§ãã
ç·šéïŒããã€ãã®ãã¹ãã«åºã¥ããšãããã¯ãã®ãããªãã¹ãŠã®èªã¿åã/æžã蟌ã¿ã«åœ±é¿ãäžãããšã¯æãããŸãããããã¯ã圱é¿ããã£ãå Žåã«ããã©ãŒãã³ã¹ãäœäžããå¯èœæ§ããããããé©ãããšã§ã¯ãããŸããã ããã§ãã -Z mutable-noalias
䜿çšãããšãäžèšã®äŸã®ããã«ã¡ã¢ãªã¢ã¯ã»ã¹ãä¿®æ£ããããããå Žåã«ãã£ãŠã¯ç¡å¹ã«ãªãå¯èœæ§ããããŸãã
@PaulGrandperrinãã®ãããã®æ°ããããŒãžã§ã³ãhttps://reviews.llvm.org/D69542ã«ããã llvm @ 9fb46a452d4e5666828c95610ceac8dcd9e4ce16ã«åºã¥ããŠããŸãã ããäžåºŠå®è¡ããŠã¿ãŸãããïŒ
æãåèã«ãªãã³ã¡ã³ã
ç§ã¯ãããåçŽãªCãã¹ãã±ãŒã¹ã«æžãããŸããïŒ-O3ãš-O0ã§ã³ã³ãã€ã«ããåºåãæ¯èŒããŸãïŒïŒ
restrict
ãåé€ãããšãCã¯noalias
ã«çžåœããåäœã¯æ£ããããšã«æ³šæããŠãã ããã ããã§ããassert(a != b)
åæ Œããrestrict
åŒã³åºãããã«UBãçºçããªãããšã蚌æããŸããäœãèµ·ãã£ãŠããã®ã§ããïŒ
mat[0]
ã¯mat[idxs[1]]
ãŸãã¯mat[1]
ã§ãšã€ãªã¢ã¹ã§ããªããšèããŠããŸãããšã«ãŽã¯ãmat[0] = 7;
ãšmat[idxs[2]] = mat[0];
éã§å€æŽã§ããŸããããšã«ãŽmat[idxs[2]] = 7;
ã«æé©åããããã®ã°ããŒãã«å€ã®çªå·ä»ãããã ãã
idxs[1] == 0
ã§ãããããmat[0]
ã¯mat[idxs[1]]
ãšãšã€ãªã¢ã¹ããŸãã ãŸãã&mat[idxs[1]]
ãcopy
ã«æž¡ããã2åç®ã®å埩ã§ã¯ãä»ã®åŒæ°ã¯&mat[1]
ã§ãããããããããªããšã¯çŽæããŸãããããšãããã¯
copy
ãã€ã³ã©ã€ã³åãããæ¹æ³ãšé¢ä¿ããããŸããnoalias
é¢æ°å±æ§ã¯ã次ã®ãããªããŒãããã³ã¹ãã¢åœä»€ã§!alias.scope
ããã³!noalias
ã¡ã¿ããŒã¿ã«å€æãããŸããéåžžãé¢æ°ãè€æ°åã€ã³ã©ã€ã³åãããå Žåãåã³ããŒã¯alias.scopeãšnoaliasã®ç¬èªã®äžæã®IDãååŸããŸããããã¯ãååŒã³åºãã
noalias
ïŒrestrict
ïŒCã¬ãã«ïŒãåŒã³åºãããšã«å€ãç°ãªãå ŽåããããŸãããã ãããã®å Žåãæåã«é¢æ°ãã«ãŒãã«ã€ã³ã©ã€ã³åããã次ã«ã«ãŒããå±éããããšãã«ã€ã³ã©ã€ã³åãããã³ãŒããè€è£œãããŸãããã®è€è£œã«ãã£ãŠIDã¯å€æŽãããŸããã ãã®ãããLLVMã¯ãã®ã©ããèããŠããªã
a
'ã®ããããã®çŒ¶å¥åb
ãåœã§ãããs'ãçç±a
第äžåã³ç¬¬äžã®é話ãšã€ãªã¢ã¹ãã2çªç®ã®åŒã³åºãããã®b
ã䜿çšããŸãïŒãã¹ãŠ&mat[0]
æããŸãïŒãé©ãã¹ãããšã«ãGCCãããã誀ã£ãŠã³ã³ãã€ã«ããåºåãç°ãªããŸãã ïŒ-O0ã§ã®clangãšGCCã¯äž¡æ¹ãšã
7 10
åºåããŸã; -O3ã§ã®clangã¯7 7
åºåããŸã; -O3ã§ã®GCCã¯10 7
åºåããŸããäœããå°ç¡ãã«ããŠãçµå±UBãè¿œå ããŸãããæ¹æ³ãããããŸãã...*ãããããå°ãè€éã§ããããã®å Žåã
copy
ã¯ãã€ã³ã¿æŒç®ã䜿çšãããäž¡æ¹ã®ãã€ã³ã¿ã«æžã蟌ããããäžçåŒa != b
ãå¿ èŠã§ããã UBã«ãªããŸãã