blob: 21e2571f73d3db0bc59b0f8f3fa6e2fa15046189 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef sw_Nucleus_hpp
16#define sw_Nucleus_hpp
17
Nicolas Capens01a97962017-07-28 17:30:51 -040018#include <cassert>
Nicolas Capens3bbc5e12016-09-27 10:49:52 -040019#include <cstdarg>
20#include <cstdint>
Nicolas Capens0bac2852016-05-07 06:09:58 -040021#include <vector>
Nicolas Capens0bac2852016-05-07 06:09:58 -040022
Nicolas Capens0bac2852016-05-07 06:09:58 -040023namespace sw
24{
Nicolas Capensac230122016-09-20 14:30:06 -040025 class Type;
Nicolas Capens19336542016-09-26 10:32:29 -040026 class Value;
Nicolas Capensb98fe5c2016-11-09 12:24:06 -050027 class SwitchCases;
Nicolas Capensc8b67a42016-09-25 15:02:52 -040028 class BasicBlock;
Nicolas Capensdaa5d912016-09-28 16:56:36 -040029 class Routine;
Nicolas Capensac230122016-09-20 14:30:06 -040030
Nicolas Capens0bac2852016-05-07 06:09:58 -040031 enum Optimization
32 {
33 Disabled = 0,
34 InstructionCombining = 1,
35 CFGSimplification = 2,
36 LICM = 3,
37 AggressiveDCE = 4,
38 GVN = 5,
39 Reassociate = 6,
40 DeadStoreElimination = 7,
41 SCCP = 8,
42 ScalarReplAggregates = 9,
43
44 OptimizationCount
45 };
46
47 extern Optimization optimization[10];
48
Nicolas Capens0bac2852016-05-07 06:09:58 -040049 class Nucleus
50 {
51 public:
52 Nucleus();
53
54 virtual ~Nucleus();
55
56 Routine *acquireRoutine(const wchar_t *name, bool runOptimizations = true);
57
Nicolas Capens19336542016-09-26 10:32:29 -040058 static Value *allocateStackVariable(Type *type, int arraySize = 0);
Nicolas Capensc8b67a42016-09-25 15:02:52 -040059 static BasicBlock *createBasicBlock();
60 static BasicBlock *getInsertBlock();
61 static void setInsertBlock(BasicBlock *basicBlock);
Nicolas Capens0bac2852016-05-07 06:09:58 -040062
Nicolas Capensac230122016-09-20 14:30:06 -040063 static void createFunction(Type *ReturnType, std::vector<Type*> &Params);
Nicolas Capens19336542016-09-26 10:32:29 -040064 static Value *getArgument(unsigned int index);
Nicolas Capens0bac2852016-05-07 06:09:58 -040065
66 // Terminators
Nicolas Capens3d7c35f2016-09-28 10:36:57 -040067 static void createRetVoid();
68 static void createRet(Value *V);
69 static void createBr(BasicBlock *dest);
70 static void createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse);
Nicolas Capens0bac2852016-05-07 06:09:58 -040071
72 // Binary operators
Nicolas Capens19336542016-09-26 10:32:29 -040073 static Value *createAdd(Value *lhs, Value *rhs);
74 static Value *createSub(Value *lhs, Value *rhs);
75 static Value *createMul(Value *lhs, Value *rhs);
76 static Value *createUDiv(Value *lhs, Value *rhs);
77 static Value *createSDiv(Value *lhs, Value *rhs);
78 static Value *createFAdd(Value *lhs, Value *rhs);
79 static Value *createFSub(Value *lhs, Value *rhs);
80 static Value *createFMul(Value *lhs, Value *rhs);
81 static Value *createFDiv(Value *lhs, Value *rhs);
82 static Value *createURem(Value *lhs, Value *rhs);
83 static Value *createSRem(Value *lhs, Value *rhs);
84 static Value *createFRem(Value *lhs, Value *rhs);
85 static Value *createShl(Value *lhs, Value *rhs);
86 static Value *createLShr(Value *lhs, Value *rhs);
87 static Value *createAShr(Value *lhs, Value *rhs);
88 static Value *createAnd(Value *lhs, Value *rhs);
89 static Value *createOr(Value *lhs, Value *rhs);
90 static Value *createXor(Value *lhs, Value *rhs);
Nicolas Capensb955d5b2016-09-28 22:36:28 -040091
92 // Unary operators
Nicolas Capens19336542016-09-26 10:32:29 -040093 static Value *createNeg(Value *V);
94 static Value *createFNeg(Value *V);
95 static Value *createNot(Value *V);
Nicolas Capens0bac2852016-05-07 06:09:58 -040096
97 // Memory instructions
Nicolas Capense12780d2016-09-27 14:18:07 -040098 static Value *createLoad(Value *ptr, Type *type, bool isVolatile = false, unsigned int align = 0);
Nicolas Capens6d738712016-09-30 04:15:22 -040099 static Value *createStore(Value *value, Value *ptr, Type *type, bool isVolatile = false, unsigned int align = 0);
Nicolas Capensd294def2017-01-26 17:44:37 -0800100 static Value *createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400101
102 // Atomic instructions
Nicolas Capens19336542016-09-26 10:32:29 -0400103 static Value *createAtomicAdd(Value *ptr, Value *value);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400104
105 // Cast/Conversion Operators
Nicolas Capens19336542016-09-26 10:32:29 -0400106 static Value *createTrunc(Value *V, Type *destType);
107 static Value *createZExt(Value *V, Type *destType);
108 static Value *createSExt(Value *V, Type *destType);
109 static Value *createFPToSI(Value *V, Type *destType);
Nicolas Capens19336542016-09-26 10:32:29 -0400110 static Value *createSIToFP(Value *V, Type *destType);
111 static Value *createFPTrunc(Value *V, Type *destType);
112 static Value *createFPExt(Value *V, Type *destType);
Nicolas Capens19336542016-09-26 10:32:29 -0400113 static Value *createBitCast(Value *V, Type *destType);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400114
115 // Compare instructions
Nicolas Capens19336542016-09-26 10:32:29 -0400116 static Value *createICmpEQ(Value *lhs, Value *rhs);
117 static Value *createICmpNE(Value *lhs, Value *rhs);
118 static Value *createICmpUGT(Value *lhs, Value *rhs);
119 static Value *createICmpUGE(Value *lhs, Value *rhs);
120 static Value *createICmpULT(Value *lhs, Value *rhs);
121 static Value *createICmpULE(Value *lhs, Value *rhs);
122 static Value *createICmpSGT(Value *lhs, Value *rhs);
123 static Value *createICmpSGE(Value *lhs, Value *rhs);
124 static Value *createICmpSLT(Value *lhs, Value *rhs);
125 static Value *createICmpSLE(Value *lhs, Value *rhs);
126 static Value *createFCmpOEQ(Value *lhs, Value *rhs);
127 static Value *createFCmpOGT(Value *lhs, Value *rhs);
128 static Value *createFCmpOGE(Value *lhs, Value *rhs);
129 static Value *createFCmpOLT(Value *lhs, Value *rhs);
130 static Value *createFCmpOLE(Value *lhs, Value *rhs);
131 static Value *createFCmpONE(Value *lhs, Value *rhs);
132 static Value *createFCmpORD(Value *lhs, Value *rhs);
133 static Value *createFCmpUNO(Value *lhs, Value *rhs);
134 static Value *createFCmpUEQ(Value *lhs, Value *rhs);
135 static Value *createFCmpUGT(Value *lhs, Value *rhs);
136 static Value *createFCmpUGE(Value *lhs, Value *rhs);
137 static Value *createFCmpULT(Value *lhs, Value *rhs);
138 static Value *createFCmpULE(Value *lhs, Value *rhs);
139 static Value *createFCmpUNE(Value *lhs, Value *rhs);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400140
Nicolas Capens0bac2852016-05-07 06:09:58 -0400141 // Vector instructions
Nicolas Capense95d5342016-09-30 11:37:28 -0400142 static Value *createExtractElement(Value *vector, Type *type, int index);
Nicolas Capens19336542016-09-26 10:32:29 -0400143 static Value *createInsertElement(Value *vector, Value *element, int index);
Nicolas Capense89cd582016-09-30 14:23:47 -0400144 static Value *createShuffleVector(Value *V1, Value *V2, const int *select);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400145
146 // Other instructions
Nicolas Capens19336542016-09-26 10:32:29 -0400147 static Value *createSelect(Value *C, Value *ifTrue, Value *ifFalse);
Nicolas Capensb98fe5c2016-11-09 12:24:06 -0500148 static SwitchCases *createSwitch(Value *control, BasicBlock *defaultBranch, unsigned numCases);
149 static void addSwitchCase(SwitchCases *switchCases, int label, BasicBlock *branch);
Nicolas Capens3d7c35f2016-09-28 10:36:57 -0400150 static void createUnreachable();
Nicolas Capens0bac2852016-05-07 06:09:58 -0400151
Nicolas Capens0bac2852016-05-07 06:09:58 -0400152 // Constant values
Nicolas Capens13ac2322016-10-13 14:52:12 -0400153 static Value *createNullValue(Type *type);
154 static Value *createConstantLong(int64_t i);
155 static Value *createConstantInt(int i);
156 static Value *createConstantInt(unsigned int i);
157 static Value *createConstantBool(bool b);
158 static Value *createConstantByte(signed char i);
159 static Value *createConstantByte(unsigned char i);
160 static Value *createConstantShort(short i);
161 static Value *createConstantShort(unsigned short i);
162 static Value *createConstantFloat(float x);
163 static Value *createNullPointer(Type *type);
164 static Value *createConstantVector(const int64_t *constants, Type *type);
165 static Value *createConstantVector(const double *constants, Type *type);
Nicolas Capens0e33ae32016-09-23 17:37:27 -0400166
Nicolas Capens13ac2322016-10-13 14:52:12 -0400167 static Type *getPointerType(Type *elementType);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400168
169 private:
170 void optimize();
Nicolas Capens0bac2852016-05-07 06:09:58 -0400171 };
Nicolas Capens0bac2852016-05-07 06:09:58 -0400172}
173
174#endif // sw_Nucleus_hpp