Mercurial > hg > CbC > CbC_llvm
comparison clang/lib/CodeGen/PatternInit.cpp @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 0572611fdcc8 |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 //===--- PatternInit.cpp - Pattern Initialization -------------------------===// | |
2 // | |
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
4 // See https://llvm.org/LICENSE.txt for license information. | |
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
6 // | |
7 //===----------------------------------------------------------------------===// | |
8 | |
9 #include "PatternInit.h" | |
10 #include "CodeGenModule.h" | |
11 #include "llvm/IR/Constant.h" | |
12 #include "llvm/IR/Type.h" | |
13 | |
14 llvm::Constant *clang::CodeGen::initializationPatternFor(CodeGenModule &CGM, | |
15 llvm::Type *Ty) { | |
16 // The following value is a guaranteed unmappable pointer value and has a | |
17 // repeated byte-pattern which makes it easier to synthesize. We use it for | |
18 // pointers as well as integers so that aggregates are likely to be | |
19 // initialized with this repeated value. | |
20 // For 32-bit platforms it's a bit trickier because, across systems, only the | |
21 // zero page can reasonably be expected to be unmapped. We use max 0xFFFFFFFF | |
22 // assuming that memory access will overlap into zero page. | |
23 const uint64_t IntValue = | |
24 CGM.getContext().getTargetInfo().getMaxPointerWidth() < 64 | |
25 ? 0xFFFFFFFFFFFFFFFFull | |
26 : 0xAAAAAAAAAAAAAAAAull; | |
27 // Floating-point values are initialized as NaNs because they propagate. Using | |
28 // a repeated byte pattern means that it will be easier to initialize | |
29 // all-floating-point aggregates and arrays with memset. Further, aggregates | |
30 // which mix integral and a few floats might also initialize with memset | |
31 // followed by a handful of stores for the floats. Using fairly unique NaNs | |
32 // also means they'll be easier to distinguish in a crash. | |
33 constexpr bool NegativeNaN = true; | |
34 constexpr uint64_t NaNPayload = 0xFFFFFFFFFFFFFFFFull; | |
35 if (Ty->isIntOrIntVectorTy()) { | |
36 unsigned BitWidth = cast<llvm::IntegerType>( | |
37 Ty->isVectorTy() ? Ty->getVectorElementType() : Ty) | |
38 ->getBitWidth(); | |
39 if (BitWidth <= 64) | |
40 return llvm::ConstantInt::get(Ty, IntValue); | |
41 return llvm::ConstantInt::get( | |
42 Ty, llvm::APInt::getSplat(BitWidth, llvm::APInt(64, IntValue))); | |
43 } | |
44 if (Ty->isPtrOrPtrVectorTy()) { | |
45 auto *PtrTy = cast<llvm::PointerType>( | |
46 Ty->isVectorTy() ? Ty->getVectorElementType() : Ty); | |
47 unsigned PtrWidth = CGM.getContext().getTargetInfo().getPointerWidth( | |
48 PtrTy->getAddressSpace()); | |
49 if (PtrWidth > 64) | |
50 llvm_unreachable("pattern initialization of unsupported pointer width"); | |
51 llvm::Type *IntTy = llvm::IntegerType::get(CGM.getLLVMContext(), PtrWidth); | |
52 auto *Int = llvm::ConstantInt::get(IntTy, IntValue); | |
53 return llvm::ConstantExpr::getIntToPtr(Int, PtrTy); | |
54 } | |
55 if (Ty->isFPOrFPVectorTy()) { | |
56 unsigned BitWidth = llvm::APFloat::semanticsSizeInBits( | |
57 (Ty->isVectorTy() ? Ty->getVectorElementType() : Ty) | |
58 ->getFltSemantics()); | |
59 llvm::APInt Payload(64, NaNPayload); | |
60 if (BitWidth >= 64) | |
61 Payload = llvm::APInt::getSplat(BitWidth, Payload); | |
62 return llvm::ConstantFP::getQNaN(Ty, NegativeNaN, &Payload); | |
63 } | |
64 if (Ty->isArrayTy()) { | |
65 // Note: this doesn't touch tail padding (at the end of an object, before | |
66 // the next array object). It is instead handled by replaceUndef. | |
67 auto *ArrTy = cast<llvm::ArrayType>(Ty); | |
68 llvm::SmallVector<llvm::Constant *, 8> Element( | |
69 ArrTy->getNumElements(), | |
70 initializationPatternFor(CGM, ArrTy->getElementType())); | |
71 return llvm::ConstantArray::get(ArrTy, Element); | |
72 } | |
73 | |
74 // Note: this doesn't touch struct padding. It will initialize as much union | |
75 // padding as is required for the largest type in the union. Padding is | |
76 // instead handled by replaceUndef. Stores to structs with volatile members | |
77 // don't have a volatile qualifier when initialized according to C++. This is | |
78 // fine because stack-based volatiles don't really have volatile semantics | |
79 // anyways, and the initialization shouldn't be observable. | |
80 auto *StructTy = cast<llvm::StructType>(Ty); | |
81 llvm::SmallVector<llvm::Constant *, 8> Struct(StructTy->getNumElements()); | |
82 for (unsigned El = 0; El != Struct.size(); ++El) | |
83 Struct[El] = initializationPatternFor(CGM, StructTy->getElementType(El)); | |
84 return llvm::ConstantStruct::get(StructTy, Struct); | |
85 } |