llvm.org GIT mirror llvm / c4b058f
Add @llvm.clear_cache builtin Implementing the LLVM part of the call to __builtin___clear_cache which translates into an intrinsic @llvm.clear_cache and is lowered by each target, either to a call to __clear_cache or nothing at all incase the caches are unified. Updating LangRef and adding some tests for the implemented architectures. Other archs will have to implement the method in case this builtin has to be compiled for it, since the default behaviour is to bail unimplemented. A Clang patch is required for the builtin to be lowered into the llvm intrinsic. This will be done next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204802 91177308-0d34-0410-b5e6-96231b3b80d8 Renato Golin 6 years ago
10 changed file(s) with 135 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
69386938 Note that runtime support may be conditional on the privilege-level code is
69396939 running at and the host platform.
69406940
6941 '``llvm.clear_cache``' Intrinsic
6942 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6943
6944 Syntax:
6945 """""""
6946
6947 ::
6948
6949 declare void @llvm.clear_cache(i8*, i8*)
6950
6951 Overview:
6952 """""""""
6953
6954 The '``llvm.clear_cache``' intrinsic provides access to the systemcall
6955 that flushes the cache at the range specified. Some targets need this
6956 to specifically flush the instruction cache when executable data changes
6957 in memory (self-modifying code). Other targets have unified intruction
6958 and data cache, so they don't need any calls.
6959
6960 Semantics:
6961 """"""""""
6962
6963 When directly supported, this intrinsic will either return a call to
6964 the appropriate cache clearing system call (usually ``__clear_cache``)
6965 when the caches are not unified (ARM, Mips) or just remove the call
6966 altogether when they are (ex. x86_64).
6967
6968 Targets must implement it directly to have either behaviour, as the
6969 default is to bail with "Not Implemented" message.
6970
69416971 Standard C Library Intrinsics
69426972 -----------------------------
69436973
512512 def int_convertuu : Intrinsic<[llvm_anyint_ty],
513513 [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
514514
515 // Clear cache intrinsic, default to ignore (ie. emit nothing)
516 // maps to void __clear_cache() on supporting platforms
517 def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
518 [], "llvm.clear_cache">;
519
515520 //===----------------------------------------------------------------------===//
516521 // Target-specific intrinsics
517522 //===----------------------------------------------------------------------===//
21072107 return false;
21082108 }
21092109
2110 /// Return the builtin name for the __builtin___clear_cache intrinsic
2111 virtual const char * getClearCacheBuiltinName() const {
2112 llvm_unreachable("Not Implemented");
2113 }
2114
21102115 /// Return the type that should be used to zero or sign extend a
21112116 /// zeroext/signext integer argument or return value. FIXME: Most C calling
21122117 /// convention requires the return type to be promoted, but this is not true
53855385 (void)getControlRoot();
53865386 return 0;
53875387 }
5388 case Intrinsic::clear_cache:
5389 return TLI->getClearCacheBuiltinName();
53885390 case Intrinsic::donothing:
53895391 // ignore
53905392 return 0;
382382 /// to just the constant itself.
383383 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
384384 Type *Ty) const override;
385
386 /// Clear cache library call
387 const char * getClearCacheBuiltinName() const {
388 return "__clear_cache";
389 }
385390
386391 protected:
387392 std::pair
582582 bool MemcpyStrSrc,
583583 MachineFunction &MF) const;
584584
585 /// Clear cache library call
586 const char * getClearCacheBuiltinName() const {
587 return "__clear_cache";
588 }
589
585590 /// isFPImmLegal - Returns true if the target can instruction select the
586591 /// specified FP immediate natively. If false, the legalizer will
587592 /// materialize the FP immediate as a load from a constant pool.
768768 /// to just the constant itself.
769769 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
770770 Type *Ty) const override;
771
772 /// Intel processors have a unified instruction and data cache
773 const char * getClearCacheBuiltinName() const {
774 return 0; // nothing to do, move along.
775 }
771776
772777 /// createFastISel - This method returns a target specific FastISel object,
773778 /// or null if the target does not support "fast" ISel.
0 ; RUN: llc %s -o - | FileCheck %s
1 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
2 target triple = "armv7--linux-gnueabihf"
3
4 @buffer = global [32 x i8] c"This is a largely unused buffer\00", align 1
5 @.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
6 @.str1 = private unnamed_addr constant [25 x i8] c"Still, largely unused...\00", align 1
7
8 define i32 @main() {
9 entry:
10 %retval = alloca i32, align 4
11 store i32 0, i32* %retval
12 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0))
13 %call1 = call i8* @strcpy(i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0), i8* getelementptr inbounds ([25 x i8]* @.str1, i32 0, i32 0)) #3
14 call void @llvm.clear_cache(i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0), i8* getelementptr inbounds (i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0), i32 32)) #3
15 %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0))
16 ret i32 0
17 }
18
19 ; CHECK: __clear_cache
20
21 declare i32 @printf(i8*, ...)
22
23 declare i8* @strcpy(i8*, i8*)
24
25 declare void @llvm.clear_cache(i8*, i8*)
0 ; RUN: llc %s -o - | FileCheck %s
1 target datalayout = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64"
2 target triple = "mips--linux-gnu"
3
4 @buffer = global [32 x i8] c"This is a largely unused buffer\00", align 1
5 @.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
6 @.str1 = private unnamed_addr constant [25 x i8] c"Still, largely unused...\00", align 1
7
8 define i32 @main() {
9 entry:
10 %retval = alloca i32, align 4
11 store i32 0, i32* %retval
12 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0))
13 %call1 = call i8* @strcpy(i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0), i8* getelementptr inbounds ([25 x i8]* @.str1, i32 0, i32 0)) #3
14 call void @llvm.clear_cache(i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0), i8* getelementptr inbounds (i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0), i32 32)) #3
15 %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0))
16 ret i32 0
17 }
18
19 ; CHECK: __clear_cache
20
21 declare i32 @printf(i8*, ...)
22
23 declare i8* @strcpy(i8*, i8*)
24
25 declare void @llvm.clear_cache(i8*, i8*)
0 ; RUN: llc %s -o - | FileCheck %s
1 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 target triple = "x86_64-unknown-linux-gnu"
3
4 @buffer = global [32 x i8] c"This is a largely unused buffer\00", align 16
5 @.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
6 @.str1 = private unnamed_addr constant [25 x i8] c"Still, largely unused...\00", align 1
7
8 define i32 @main() {
9 entry:
10 %retval = alloca i32, align 4
11 store i32 0, i32* %retval
12 %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0))
13 %call1 = call i8* @strcpy(i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0), i8* getelementptr inbounds ([25 x i8]* @.str1, i32 0, i32 0)) #3
14 call void @llvm.clear_cache(i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0), i8* getelementptr inbounds (i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0), i32 32)) #3
15 %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([32 x i8]* @buffer, i32 0, i32 0))
16 ret i32 0
17 }
18
19 ; CHECK-NOT: __clear_cache
20
21 declare i32 @printf(i8*, ...)
22
23 declare i8* @strcpy(i8*, i8*)
24
25 declare void @llvm.clear_cache(i8*, i8*)