@@ -78,6 +78,126 @@ std::string LangOptions::getOpenCLVersionString() const {
78
78
return Result;
79
79
}
80
80
81
+ void LangOptions::setLangDefaults (LangOptions &Opts, Language Lang,
82
+ const llvm::Triple &T,
83
+ std::vector<std::string> &Includes,
84
+ LangStandard::Kind LangStd) {
85
+ // Set some properties which depend solely on the input kind; it would be nice
86
+ // to move these to the language standard, and have the driver resolve the
87
+ // input kind + language standard.
88
+ //
89
+ // FIXME: Perhaps a better model would be for a single source file to have
90
+ // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std)
91
+ // simultaneously active?
92
+ if (Lang == Language::Asm) {
93
+ Opts.AsmPreprocessor = 1 ;
94
+ } else if (Lang == Language::ObjC || Lang == Language::ObjCXX) {
95
+ Opts.ObjC = 1 ;
96
+ }
97
+
98
+ if (LangStd == LangStandard::lang_unspecified)
99
+ LangStd = getDefaultLanguageStandard (Lang, T);
100
+ const LangStandard &Std = LangStandard::getLangStandardForKind (LangStd);
101
+ Opts.LangStd = LangStd;
102
+ Opts.LineComment = Std.hasLineComments ();
103
+ Opts.C99 = Std.isC99 ();
104
+ Opts.C11 = Std.isC11 ();
105
+ Opts.C17 = Std.isC17 ();
106
+ Opts.C2x = Std.isC2x ();
107
+ Opts.CPlusPlus = Std.isCPlusPlus ();
108
+ Opts.CPlusPlus11 = Std.isCPlusPlus11 ();
109
+ Opts.CPlusPlus14 = Std.isCPlusPlus14 ();
110
+ Opts.CPlusPlus17 = Std.isCPlusPlus17 ();
111
+ Opts.CPlusPlus20 = Std.isCPlusPlus20 ();
112
+ Opts.CPlusPlus2b = Std.isCPlusPlus2b ();
113
+ Opts.GNUMode = Std.isGNUMode ();
114
+ Opts.GNUCVersion = 0 ;
115
+ Opts.HexFloats = Std.hasHexFloats ();
116
+ Opts.ImplicitInt = Std.hasImplicitInt ();
117
+ Opts.WChar = Std.isCPlusPlus ();
118
+ Opts.Digraphs = Std.hasDigraphs ();
119
+
120
+ Opts.HLSL = Lang == Language::HLSL;
121
+
122
+ // Set OpenCL Version.
123
+ Opts.OpenCL = Std.isOpenCL ();
124
+ if (LangStd == LangStandard::lang_opencl10)
125
+ Opts.OpenCLVersion = 100 ;
126
+ else if (LangStd == LangStandard::lang_opencl11)
127
+ Opts.OpenCLVersion = 110 ;
128
+ else if (LangStd == LangStandard::lang_opencl12)
129
+ Opts.OpenCLVersion = 120 ;
130
+ else if (LangStd == LangStandard::lang_opencl20)
131
+ Opts.OpenCLVersion = 200 ;
132
+ else if (LangStd == LangStandard::lang_opencl30)
133
+ Opts.OpenCLVersion = 300 ;
134
+ else if (LangStd == LangStandard::lang_openclcpp10)
135
+ Opts.OpenCLCPlusPlusVersion = 100 ;
136
+ else if (LangStd == LangStandard::lang_openclcpp2021)
137
+ Opts.OpenCLCPlusPlusVersion = 202100 ;
138
+ else if (LangStd == LangStandard::lang_hlsl2015)
139
+ Opts.HLSLVersion = (unsigned )LangOptions::HLSL_2015;
140
+ else if (LangStd == LangStandard::lang_hlsl2016)
141
+ Opts.HLSLVersion = (unsigned )LangOptions::HLSL_2016;
142
+ else if (LangStd == LangStandard::lang_hlsl2017)
143
+ Opts.HLSLVersion = (unsigned )LangOptions::HLSL_2017;
144
+ else if (LangStd == LangStandard::lang_hlsl2018)
145
+ Opts.HLSLVersion = (unsigned )LangOptions::HLSL_2018;
146
+ else if (LangStd == LangStandard::lang_hlsl2021)
147
+ Opts.HLSLVersion = (unsigned )LangOptions::HLSL_2021;
148
+ else if (LangStd == LangStandard::lang_hlsl202x)
149
+ Opts.HLSLVersion = (unsigned )LangOptions::HLSL_202x;
150
+
151
+ // OpenCL has some additional defaults.
152
+ if (Opts.OpenCL ) {
153
+ Opts.AltiVec = 0 ;
154
+ Opts.ZVector = 0 ;
155
+ Opts.setDefaultFPContractMode (LangOptions::FPM_On);
156
+ Opts.OpenCLCPlusPlus = Opts.CPlusPlus ;
157
+ Opts.OpenCLPipes = Opts.getOpenCLCompatibleVersion () == 200 ;
158
+ Opts.OpenCLGenericAddressSpace = Opts.getOpenCLCompatibleVersion () == 200 ;
159
+
160
+ // Include default header file for OpenCL.
161
+ if (Opts.IncludeDefaultHeader ) {
162
+ if (Opts.DeclareOpenCLBuiltins ) {
163
+ // Only include base header file for builtin types and constants.
164
+ Includes.push_back (" opencl-c-base.h" );
165
+ } else {
166
+ Includes.push_back (" opencl-c.h" );
167
+ }
168
+ }
169
+ }
170
+
171
+ Opts.HIP = Lang == Language::HIP;
172
+ Opts.CUDA = Lang == Language::CUDA || Opts.HIP ;
173
+ if (Opts.HIP ) {
174
+ // HIP toolchain does not support 'Fast' FPOpFusion in backends since it
175
+ // fuses multiplication/addition instructions without contract flag from
176
+ // device library functions in LLVM bitcode, which causes accuracy loss in
177
+ // certain math functions, e.g. tan(-1e20) becomes -0.933 instead of 0.8446.
178
+ // For device library functions in bitcode to work, 'Strict' or 'Standard'
179
+ // FPOpFusion options in backends is needed. Therefore 'fast-honor-pragmas'
180
+ // FP contract option is used to allow fuse across statements in frontend
181
+ // whereas respecting contract flag in backend.
182
+ Opts.setDefaultFPContractMode (LangOptions::FPM_FastHonorPragmas);
183
+ } else if (Opts.CUDA ) {
184
+ if (T.isSPIRV ()) {
185
+ // Emit OpenCL version metadata in LLVM IR when targeting SPIR-V.
186
+ Opts.OpenCLVersion = 200 ;
187
+ }
188
+ // Allow fuse across statements disregarding pragmas.
189
+ Opts.setDefaultFPContractMode (LangOptions::FPM_Fast);
190
+ }
191
+
192
+ Opts.RenderScript = Lang == Language::RenderScript;
193
+
194
+ // OpenCL, C++ and C2x have bool, true, false keywords.
195
+ Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C2x ;
196
+
197
+ // OpenCL has half keyword
198
+ Opts.Half = Opts.OpenCL ;
199
+ }
200
+
81
201
FPOptions FPOptions::defaultWithoutTrailingStorage (const LangOptions &LO) {
82
202
FPOptions result (LO);
83
203
return result;
0 commit comments