From 3f29228a10e65eadc23ccd40dc8fbe1efe268892 Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Wed, 24 Apr 2024 20:29:30 +0200 Subject: [PATCH 001/733] [libc++][format] Adds an escaped output benchmark. (#88020) This is a preparation to measure the performance impact of - P2713R1 Escaping improvements in std::format and its performance improving followup patch. --- libcxx/benchmarks/CMakeLists.txt | 1 + ...ormat_spec_string_unicode_escape.bench.cpp | 303 ++++++++++++++++++ 2 files changed, 304 insertions(+) create mode 100644 libcxx/benchmarks/std_format_spec_string_unicode_escape.bench.cpp diff --git a/libcxx/benchmarks/CMakeLists.txt b/libcxx/benchmarks/CMakeLists.txt index 527a2acf2d3b..5dc3be0c367e 100644 --- a/libcxx/benchmarks/CMakeLists.txt +++ b/libcxx/benchmarks/CMakeLists.txt @@ -224,6 +224,7 @@ set(BENCHMARK_TESTS shared_mutex_vs_mutex.bench.cpp stop_token.bench.cpp std_format_spec_string_unicode.bench.cpp + std_format_spec_string_unicode_escape.bench.cpp string.bench.cpp stringstream.bench.cpp system_error.bench.cpp diff --git a/libcxx/benchmarks/std_format_spec_string_unicode_escape.bench.cpp b/libcxx/benchmarks/std_format_spec_string_unicode_escape.bench.cpp new file mode 100644 index 000000000000..3b5a1c4340c3 --- /dev/null +++ b/libcxx/benchmarks/std_format_spec_string_unicode_escape.bench.cpp @@ -0,0 +1,303 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This test formats a larger piece of text in "escaped" mode. It uses several +// datasets to give an impression how the amount of multibyte UTF-8 sequences +// and larger grapheme clusters affect the performance. + +#ifndef _LIBCPP_HAS_NO_UNICODE + +# include +# include + +# include "benchmark/benchmark.h" + +# include "make_string.h" + +# define SV(S) MAKE_STRING_VIEW(CharT, S) + +// generated with https://generator.lorem-ipsum.info/_latin + +template +std::basic_string_view ascii_text() { + return SV( + R"( Lorem ipsum dolor sit amet, ne sensibus evertitur aliquando his. +Iuvaret fabulas qui ex, ex iriure iisque nostrum mea. Solum +pericula qui ad. Elitr oporteat ius ad. + +Quas rationibus ad mel. Appellantur intellegebat ad mei, ius audire volumus +consectetuer id. Ei sit definitionem mediocritatem, vim indoctum intellegat id, +dicta laboramus instructior in vix. Mel an quando malorum, id vis mollis +invidunt, placerat maiestatis comprehensam ut cum. Suas regione interesset id +per, et docendi accumsan has, autem atomorum est te. + +Cu debitis ancillae sea, alii definitiones ex cum, vim no erat antiopam. Eam et +unum quas scriptorem. An bonorum elaboraret complectitur nam, vim ei persecuti +democritum mediocritatem. Suscipit platonem signiferumque ei cum, in sale +volutpat ocurreret vel. Te vel nihil nominavi adipiscing, stet ancillae mel ea. +Sit detraxit menandri platonem ea, cum at tale viris virtute. + +Regione detraxit gloriatur sit eu, sonet labitur sententiae et pro, at sit +alterum aliquid interpretaris. Sonet voluptua duo id, vix ea accumsan +liberavisse. Nam id commune probatus contentiones. Et zril dolore laudem duo, +ea usu mollis melius referrentur, vel ex case consequuntur. Id nam illum mollis +ponderum. Quis tamquam ullamcorper sed ne, legimus vituperatoribus est id. + +Et eum probo consulatu. At eos errem aliquando theophrastus, sea ad eius omnis. +No vis iusto scriptorem adversarium, dicat viderer ea sit. Et veri euripidis +sea, justo putent iudicabit vim id. Sea suas tincidunt vituperatoribus in. Ne +eam aeterno sensibus concludaturque, solet legere his id, usu ei dicat +dissentiunt. Est et autem erant. + +Per quod laboramus an. Dico voluptua at mea, an animal minimum eum. Pri an +option salutatus, causae feugiat menandri an sed. Voluptaria dissentiet vix ut, +alii solet te quo, in facer ceteros eos. Ad nibh meis percipitur sit, +aliquam molestie cu vis, iisque malorum interesset et eos. + +Eos in feugiat insolens abhorreant. Ea tale esse alienum has, mel et saperet +appellantur, aliquip salutandi deterruisset ut mel. Eos ei quod simul +interpretaris, aeque elitr putent per at, et veri eripuit ceteros his. Cu pro +meis aperiam volutpat, ex alterum scripserit ius, scriptorem deterruisset eu +qui. Graeco debitis lobortis cu mea. + +Alii corpora id ius, cu quo oblique eloquentiam. Et duis civibus atomorum sea, +veniam utroque scriptorem vim cu. Ut oratio eruditi mediocritatem est. Amet +nibh dolore mea ea, tollit laoreet eligendi qui ex, cu essent forensibus +his. + +Usu ex ipsum apeirian, eos congue scripserit omittantur et. Ea eum persecuti +deseruisse, probatus torquatos est no, in has mutat mundi dolorem. Albucius +sensibus ex cum. Ferri virtute referrentur an per, est choro option bonorum ex. + +Quando accusam vis te, tale mazim et pro. Magna dolorem tincidunt +nec te, albucius adipisci ad pri. Magna facilisi adipisci at usu, et vel +dissentiunt neglegentur, prima audiam vocibus an duo. Enim detracto te sea, mel +quis dicit gubergren ex, iusto adversarium consequuntur per ne. + +)"); +} + +template +std::basic_string_view unicode_text() { + return SV( + R"(Lōrem ipsūm dolor sīt æmeÞ, ea vel nostrud feuġǣit, muciūs tēmporiȝus +refērrēnÞur no mel, quo placērǽt consecÞetuer cū. Veri soƿet euripīðis id has, +sumo paulō dissentias duo eī, dētrāxīt neglēgeƿtur ið prī. Sēd option oporÞerē +no. Nec ēū nēmore mentitum. Veri prōȝo faċilis āt vīm. + +Ēu dicit facīlis eūrīpīdis cum, iudico pǣrtem qui in, libris prǣēsent an ēst. +Æt sit quoðsi impētus, nec ex qūaeque honestǣtīs. Fiērēƿt ƿōluisse verterem iƿ +ēst. Meī eæ apēriæm fierent peÞentīūm. Eæm officiīs reprehēndunt nē. + +Ut vel quodsī contentioƿes, his eū dignissim īnstruċÞior. Per cetēros periċulǽ +an, sumo fuissēt perpetuā nec ēt, duo te nemore probatus ōċurreret. Mel ǣd +civībus ocūrreret. Ex nostro ǣliquam usu, ex Þātīon adipiscī qui. Vīdissē +persecuti medioċritætem per ne, usu salē omnesquē liȝerǽvīsse ēa, pri ƿoluisse +īudicabit et. No summo quiðǣm nec, vim ēi nūmqūam sænctus concepÞǣm. Reque +doceƿdi īn īus, porro eripuiÞ intērprētaris pri in. + +Idquē hǣbēmus nominati vix cū. AÞ prō ǽmēt elit periculæ. Has virīs viderer ān. +Mel in suās pericūlīs āppellantur, nonumes deserūƿt ǽðversarium eā has. ĒliÞ +possīt commuƿe no ēsÞ, niȝh aċcusāmūs volūpÞatum no mel, ut quō ciȝo ðiceret. +Inǣni scripta quālīsque nē qūi, ad ipsūm persecuÞi mediōcritæÞēm vel. + +Ǣppetere definitiōnes mel id. Leġerē āliquip nam eǣ, rēgione viderer pǣtrioque +duo te, meƿāƿdri prodēsseÞ ex hīs. Solum quidam eæ iūs, mēl ǣt sapientem +expliċari. Īƿ ǣċcusǣm phǽedrum pro, ex pro dēleƿit detræxit hendrerīt, sit āgam +quidām pertinax uÞ. Ēssent rætionibus eǽ vēl, quo ān labore nusquæm nominǣti. + +Te alii cōnseÞetur ƿam, eam ēt puteƿÞ ðissentiæs. Qūi alii dicānt repuðiære ēā, +nō mel ferri nūsquam. Ea vim impedīt vertērem, ǣn per veri Þīmeam. SiÞ ōmitÞǽm +necēssitǣÞibus ex, ƿe vis inǣni pærtem invenire. Īd ðolores ċonsēċÞeÞuer usu, +īd vis nisl dēnique luptǣtūm. Pro ǽd ēverti option dēserūƿt, nec te ōðiō +cīvībūs. + +Ēæ nibh æccommodarē eum. Ne etiæm īudico dicunt duo, quo tēmpor populo insōlens +nē. Ēos eÞ ēirmod prǽēsēƿt. Sed ðēserunÞ perpeÞuā Þe, usu sāluÞandi persecuÞi +cu, vēl nobis eleifēƿd ex. + +Ƿe zrīl ūtīnam lǣtīne eǣm, eā vim rebum omitÞǣm aðipisciƿg. Amet inermis +epiċūri ut est, eu duo hīnc periċulis. Mel no reque simul volupÞātum, ex mutat +lāudem tacīmatēs cum. Te hǣs summo iƿteġre recteque. No iūs dicerēt +ðisputǽtioƿi. Vim ōmnis deleƿiÞi honestātis ēǽ. + +Nec detrǣcto pērcipitur ne. Ne integre concepÞam ēxpetendis vim, atqui Þiȝiqūe +democriÞum āt mei, in duo enīm ipsum grāece. Rebum ðefīnīÞionem āt pri, ēt sit +brute periculis. Ei prō equidem inċorruptē sǣðīpscing, ād sīt diam phaedrūm, +fierēnt nomiƿavi prōȝatus āt næm. Wisi ƿæÞūm coƿsecteÞuer usū ea. +)"); +} + +template +std::basic_string_view cyrillic_text() { + return SV( + R"(Лорем ипсум долор сит амет, еу диам тамяуам принципес вис, еяуидем +цонцептам диспутандо яуи цу, иус ад натум нулла граеци. Цибо дицит омниум нец +цу, еу бруте номинави диссентиет яуо. Омниум лаборамус еу хас. Дицат +диспутатиони вис еу, цу еос миним атоморум инцидеринт. Пер хабео рецтеяуе +дигниссим ан, ех яуо сенсибус торяуатос, ан. + +Ут перпетуа партиендо принципес хис. Ат симул ностер аппареат пер. Пурто вирис +ет хис, мазим дицерет при ет. Хис саперет тибияуе сцаевола еу, сит солет +вивендум цонсеяуат те. Ид оффициис перпетуа ассентиор яуи, сед аугуе афферт +симилияуе ад, ех адмодум постулант иус. + +Про дицунт волуптатум диспутатиони ат. Вел патриояуе персецути еа, цетерос +диспутатиони ин сед, нам те веро цлита малуиссет. Цу неглегентур инструцтиор +интерпретарис еам, ипсум фабулас еи вел. Еи адхуц деленити нам, аугуе +демоцритум при ан. Вим мелиоре проприае ид, албуциус волуптуа цоррумпит дуо ан. +Латине иуварет пер ут, иус еа мунере ерипуит санцтус. + +Модус тритани иус не, вим ут мелиоре мандамус, лабитур опортере дуо но. Ад нец +витае фацилис инцоррупте, цу сед толлит сцрипторем. Сит лудус инимицус +волуптариа не. Иисяуе антиопам сапиентем сед еу. Путент волуптуа сит ех, ат иус +ребум епицури, яуи моллис елигенди ех. Проприае нолуиссе цу сеа, путент поссит +адверсариум про не. + +Ид яуо прима бонорум, дуо форенсибус яуаерендум еи, еум бруте мунере те. Еам +риденс граецо ех, аеяуе санцтус маиорум ан вел. Либрис санцтус утрояуе ест но, +еам ат реяуе порро тинцидунт, ут хинц иллуд патриояуе хис. Не солет оффендит +форенсибус хас, тамяуам опортеат елаборарет те нец, еу аугуе примис маиорум +еам. Аутем вениам импедит вис ин, прима елитр пхаедрум ест еу.)"); +} + +template +std::basic_string_view japanese_text() { + return SV( + R"(入ト年媛ろ舗学ラロ準募ケカ社金スノ屋検れう策他セヲシ引口ぎ集7独ぱクふ出車ぽでぱ円輪ルノ受打わ。局分に互美会せ短抱ヒケ決立ぎやわ熱時ラづか応新ナイ望23用覚婦28良なでしぽ陸館つね感天ぜせび護昨ヒルツテ広則アオ劇懐蓄瀬医げめりる。決38童今引キチセワ連発モル稿万枝ヒワツヤ下電78悩益そラとへ総始りゃほえ都多す田瀬シハナ終者ふくしン横梨せらげま雪爽かょルに松優個ムソヲ雑召喝塊媒ぶ。 + +紙ヤ景異ミノオ誤求レ移著ヤエヨメ広庫テハヌサ君検あ必参ワ火面るね声著ン間売力を数20談すがス禁化ッを。起そり予浩ド進皇キ試属が震二トヌ真佳速すずちし件諏フウチ聞在ス会雄ノミ必筋80戦ぶさほド聞2涙属どスれ映聞ネ掲実べ。 + +8福びり属稿づ徳鎌ニル涼問ゃごるリ付92済トぎけッ康30業づむはつ治然二生入ざひ有動ハワチ発談ニスツ魚困摘策送ざ。個時着そてら新新ヌ鉄報たは作主ずリ可輸改量ルおず井認つてぜな会大ぼすぶし全戸ノハケレ貯治たざリな祖間ムリキ断会仕べせど。委暮ど象週トクワ流開タハ硬給ツタウ者善マラノヱ断稿リヲ東毎ツヨマ井藤ルょへ境同論エ愛図ッらフリ基38属慣葬8携ヱ校図おに岐題しね要月レユ展省わトど。 + +担がは顔研リ目問いぽべ挙介ん入番ネヌイ栄県し改治ラス健第モム得続加ホウ嘉宿置首本やぞ。78毎まが現設記ほぜね場歩ユアルヒ東的ヒ姿役ネヲ聞能ラシマヒ際形トくゃ政能万の付結ス国1教レツ引写イど扱澤は膚言けリいべ橋柔薄組こよじ。浩報すンつひ崎正念方と夫地クざす情阪スで抜長ネ娘回ハツ止資ヘニ並辞ロノ展師質18打テネ岡時ノモ泉95務えぴひつ速申後延んフるせ。 + +店てラ載独マシフ理心ス型部米た読石カ料応掲ケカキ打月在ユテニ採材イ並発イヒト旅錯っめし模能りせば連確え会准揮が。器にト画軍にぶイら式東みそお前姿リいけに身47却6記け岸5体会ゃばま映8碁よぽだ経9名トびち更躍うにふ裏高もそ提旅さぼえス。賞ぞだ月係ソ知建振イナシ説並イ見書傳ヨミ問回級エシ出所師阪ト転権がし渡平ルモケ新完ハ玲女ロトシ導複トうよふ。 + +化シセチ町74掲ネテトオ連対ヒハチモ経後ッ断連カロワ待業ぼぽねか百都へがい始塗ごげ寺帰んぽ逆力るず選英堂衛掛焼ゅ。自生トサリ探就的らね江球リルスツ主嘆4権伝ざが避掲う慶合ワ百29暮ネヤクム書能部あが席小フア部親票ーむとこ。3説ひっぜ約毎伎ナキリ缶近くなず員45姿えにけろ値付ワ着知ソルキ日医ず集新エウカケ投国チ生目ゃ棋運ぐのか寄募オチ性注経どドんて止代わくかな端期幕はかク。 +)"); +} + +template +std::basic_string_view emoji_text() { + return SV( + R"( +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 +\U0001F636\u200D\U0001F32B\uFE0F +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF + +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 + +\U0001F636\u200D\U0001F32B\uFE0F + +\U0001F44B\U0001F3FB\U0001F44B\U0001F3FC\U0001F44B\U0001F3FD\U0001F44B\U0001F3FE\U0001F44B\U0001F3FF + +\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466\U0001F1E8\U0001F1E6 + +\U0001F984 + +)"); +} + +template +void BM_escaped(benchmark::State& state, std::basic_string_view input) { + CharT buffer[25'000]; + + if constexpr (std::same_as) { + // Make sure the output buffer is large enough. + assert(std::formatted_size("{}", input) == 3000); + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(buffer, "{:?}", input)); + } else { + for (auto _ : state) + benchmark::DoNotOptimize(std::format_to(buffer, L"{:?}", input)); + } +} + +template +void BM_ascii_escaped(benchmark::State& state) { + BM_escaped(state, ascii_text()); +} + +template +void BM_unicode_escaped(benchmark::State& state) { + BM_escaped(state, unicode_text()); +} + +template +void BM_cyrillic_escaped(benchmark::State& state) { + BM_escaped(state, cyrillic_text()); +} + +template +void BM_japanese_escaped(benchmark::State& state) { + BM_escaped(state, japanese_text()); +} + +template +void BM_emoji_escaped(benchmark::State& state) { + BM_escaped(state, emoji_text()); +} + +BENCHMARK_TEMPLATE(BM_ascii_escaped, char); +BENCHMARK_TEMPLATE(BM_unicode_escaped, char); +BENCHMARK_TEMPLATE(BM_cyrillic_escaped, char); +BENCHMARK_TEMPLATE(BM_japanese_escaped, char); +BENCHMARK_TEMPLATE(BM_emoji_escaped, char); + +BENCHMARK_TEMPLATE(BM_ascii_escaped, wchar_t); +BENCHMARK_TEMPLATE(BM_unicode_escaped, wchar_t); +BENCHMARK_TEMPLATE(BM_cyrillic_escaped, wchar_t); +BENCHMARK_TEMPLATE(BM_japanese_escaped, wchar_t); +BENCHMARK_TEMPLATE(BM_emoji_escaped, wchar_t); + +int main(int argc, char** argv) { + benchmark::Initialize(&argc, argv); + if (benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + + benchmark::RunSpecifiedBenchmarks(); +} +#else +int main(int, char**) { return 0; } +#endif -- GitLab From 007e859258540cef0dcb1f0a1bdd9e74111f9ba0 Mon Sep 17 00:00:00 2001 From: Abhinav Garg <39309352+abhigargrepo@users.noreply.github.com> Date: Thu, 25 Apr 2024 00:06:05 +0530 Subject: [PATCH 002/733] AMDGPU: Pre-commit test to verify mode change in fp constrained operations (#88858) This test will check the mode register in case of constrained floating point operations. --------- Co-authored-by: Matt Arsenault --- .../AMDGPU/mode-register-fpconstrain.ll | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 llvm/test/CodeGen/AMDGPU/mode-register-fpconstrain.ll diff --git a/llvm/test/CodeGen/AMDGPU/mode-register-fpconstrain.ll b/llvm/test/CodeGen/AMDGPU/mode-register-fpconstrain.ll new file mode 100644 index 000000000000..2403aeaa4428 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/mode-register-fpconstrain.ll @@ -0,0 +1,43 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 %s -o - | FileCheck -check-prefix=GCN %s + +; The si-mode-register pass is changing the default mode for FP constrained operations. +; It must ignore for strictfp functions. + +define double @ignoreStrictfp(double noundef %a, double noundef %b) #0 { +; GCN-LABEL: ignoreStrictfp: +; GCN: ; %bb.0: +; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GCN-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_MODE, 2, 2), 1 +; GCN-NEXT: s_nop 1 +; GCN-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_MODE, 2, 1), 0 +; GCN-NEXT: v_add_f64 v[0:1], v[0:1], v[2:3] +; GCN-NEXT: s_setpc_b64 s[30:31] + tail call void @llvm.amdgcn.s.setreg(i32 2177, i32 1) + %val = tail call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 + ret double %val +} + +define double @set_fpenv(double noundef %a, double noundef %b) #0 { +; GCN-LABEL: set_fpenv: +; GCN: ; %bb.0: ; %entry +; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GCN-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_MODE, 0, 23), 4 +; GCN-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_TRAPSTS, 0, 5), 0 +; GCN-NEXT: s_nop 0 +; GCN-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_MODE, 2, 1), 0 +; GCN-NEXT: v_add_f64 v[0:1], v[0:1], v[2:3] +; GCN-NEXT: s_setpc_b64 s[30:31] +entry: + call void @llvm.set.fpenv.i64(i64 4) + %val = tail call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") #0 + ret double %val +} + +declare void @llvm.amdgcn.s.setreg(i32 immarg, i32) + +declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata) + +declare void @llvm.set.fpenv.i64(i64) + +attributes #0 = { strictfp } -- GitLab From d421a6c9ef1dd286832fce3b4f955d4ba99ce192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Warzy=C5=84ski?= Date: Wed, 24 Apr 2024 19:47:28 +0100 Subject: [PATCH 003/733] [flang][driver] Remove `flang -help` tests (#89504) These tests were introduced when the Flang driver was originally incepted. Back then, `flang-new` only supported a handful of basic options (e.g. `-v`, `-help`, `-E`) and those `-help` tests were used to guard against Clang options "leaking" into `flang-new -help`. With the introduction of the concept of "visibility" (see https://reviews.llvm.org/D157837 and https://reviews.llvm.org/D157151), these tests are effectively redundant. Also, with the number of flags growing, these tests are getting rather brittle. --- flang/test/Driver/driver-help-hidden.f90 | 173 -------------- flang/test/Driver/driver-help.f90 | 283 ----------------------- 2 files changed, 456 deletions(-) delete mode 100644 flang/test/Driver/driver-help-hidden.f90 diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 deleted file mode 100644 index b5bb0f1c1b25..000000000000 --- a/flang/test/Driver/driver-help-hidden.f90 +++ /dev/null @@ -1,173 +0,0 @@ - -!-------------------------- -! FLANG DRIVER (flang-new) -!-------------------------- -! RUN: %flang --help-hidden 2>&1 | FileCheck %s -! RUN: not %flang -help-hidden 2>&1 | FileCheck %s --check-prefix=ERROR-FLANG - -!---------------------------------------- -! FLANG FRONTEND DRIVER (flang-new -fc1) -!---------------------------------------- -! RUN: not %flang_fc1 --help-hidden 2>&1 | FileCheck %s --check-prefix=ERROR-FLANG-FC1 -! RUN: not %flang_fc1 -help-hidden 2>&1 | FileCheck %s --check-prefix=ERROR-FLANG-FC1 - -! CHECK:USAGE: flang-new -! CHECK-EMPTY: -! CHECK-NEXT: DRIVER OPTIONS: -! CHECK-NEXT: --driver-mode= Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl' or 'flang' -! CHECK-EMPTY: -! CHECK-NEXT:OPTIONS: -! CHECK-NEXT: -### Print (but do not run) the commands to run for this compilation -! CHECK-NEXT: -ccc-print-phases Dump list of actions to perform -! CHECK-NEXT: -cpp Enable predefined and command line preprocessor macros -! CHECK-NEXT: -c Only run preprocess, compile, and assemble steps -! CHECK-NEXT: -dM Print macro definitions in -E mode instead of normal output -! CHECK-NEXT: -dumpmachine Display the compiler's target processor -! CHECK-NEXT: -dumpversion Display the version of the compiler -! CHECK-NEXT: -D = Define to (or 1 if omitted) -! CHECK-NEXT: -emit-llvm Use the LLVM representation for assembler and object files -! CHECK-NEXT: -E Only run the preprocessor -! CHECK-NEXT: -falternative-parameter-statement -! CHECK-NEXT: Enable the old style PARAMETER statement -! CHECK-NEXT: -fapprox-func Allow certain math function calls to be replaced with an approximately equivalent calculation -! CHECK-NEXT: -fbackslash Specify that backslash in string introduces an escape character -! CHECK-NEXT: -fcolor-diagnostics Enable colors in diagnostics -! CHECK-NEXT: -fconvert= Set endian conversion of data for unformatted files -! CHECK-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type -! CHECK-NEXT: -fdefault-integer-8 Set the default integer and logical kind to an 8 byte wide type -! CHECK-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type -! CHECK-NEXT: -ffast-math Allow aggressive, lossy floating-point optimizations -! CHECK-NEXT: -ffixed-form Process source files in fixed form -! CHECK-NEXT: -ffixed-line-length= -! CHECK-NEXT: Use as character line width in fixed mode -! CHECK-NEXT: -ffp-contract= Form fused FP ops (e.g. FMAs) -! CHECK-NEXT: -ffree-form Process source files in free form -! CHECK-NEXT: -fhonor-infinities Specify that floating-point optimizations are not allowed that assume arguments and results are not +-inf. -! CHECK-NEXT: -fhonor-nans Specify that floating-point optimizations are not allowed that assume arguments and results are not NANs. -! CHECK-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements -! CHECK-NEXT: -finput-charset= Specify the default character set for source files -! CHECK-NEXT: -fintegrated-as Enable the integrated assembler -! CHECK-NEXT: -fintrinsic-modules-path -! CHECK-NEXT: Specify where to find the compiled intrinsic modules -! CHECK-NEXT: -flang-deprecated-no-hlfir -! CHECK-NEXT: Do not use HLFIR lowering (deprecated) -! CHECK-NEXT: -flang-experimental-hlfir -! CHECK-NEXT: Use HLFIR lowering (experimental) -! CHECK-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics -! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations -! CHECK-NEXT: -flto=auto Enable LTO in 'full' mode -! CHECK-NEXT: -flto=jobserver Enable LTO in 'full' mode -! CHECK-NEXT: -flto= Set LTO mode -! CHECK-NEXT: -flto Enable LTO in 'full' mode -! CHECK-NEXT: -fms-runtime-lib= -! CHECK-NEXT: Select Windows run-time library -! CHECK-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE -! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics -! CHECK-NEXT: -fno-fortran-main Do not include Fortran_main.a (provided by Flang) when linking -! CHECK-NEXT: -fno-integrated-as Disable the integrated assembler -! CHECK-NEXT: -fno-lto Disable LTO mode (default) -! CHECK-NEXT: -fno-ppc-native-vector-element-order -! CHECK-NEXT: Specifies PowerPC non-native vector element order -! CHECK-NEXT: -fno-rtlib-add-rpath Do not add -rpath with architecture-specific resource directory to the linker flags. When --hip-link is specified, do not add -rpath with HIP runtime library directory to the linker flags -! CHECK-NEXT: -fno-signed-zeros Allow optimizations that ignore the sign of floating point zeros -! CHECK-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default) -! CHECK-NEXT: -fno-version-loops-for-stride -! CHECK-NEXT: Do not create unit-strided loops (default) -! CHECK-NEXT: -fomit-frame-pointer Omit the frame pointer from functions that don't need it. Some stack unwinding cases, such as profilers and sanitizers, may prefer specifying -fno-omit-frame-pointer. On many targets, -O1 and higher omit the frame pointer by default. -m[no-]omit-leaf-frame-pointer takes precedence for leaf functions -! CHECK-NEXT: -fopenacc Enable OpenACC -! CHECK-NEXT: -fopenmp-assume-no-nested-parallelism -! CHECK-NEXT: Assert no nested parallel regions in the GPU -! CHECK-NEXT: -fopenmp-assume-no-thread-state -! CHECK-NEXT: Assert no thread in a parallel region modifies an ICV -! CHECK-NEXT: -fopenmp-target-debug Enable debugging in the OpenMP offloading device RTL -! CHECK-NEXT: -fopenmp-targets= -! CHECK-NEXT: Specify comma-separated list of triples OpenMP offloading targets to be supported -! CHECK-NEXT: -fopenmp-version= -! CHECK-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang -! CHECK-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. -! CHECK-NEXT: -foptimization-record-file= -! CHECK-NEXT: Specify the output name of the file containing the optimization remarks. Implies -fsave-optimization-record. On Darwin platforms, this cannot be used with multiple -arch options. -! CHECK-NEXT: -foptimization-record-passes= -! CHECK-NEXT: Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes) -! CHECK-NEXT: -fpass-plugin= Load pass plugin from a dynamic shared object file (only with new pass manager). -! CHECK-NEXT: -fppc-native-vector-element-order -! CHECK-NEXT: Specifies PowerPC native vector element order (default) -! CHECK-NEXT: -freciprocal-math Allow division operations to be reassociated -! CHECK-NEXT: -fropi Generate read-only position independent code (ARM only) -! CHECK-NEXT: -frtlib-add-rpath Add -rpath with architecture-specific resource directory to the linker flags. When --hip-link is specified, also add -rpath with HIP runtime library directory to the linker flags -! CHECK-NEXT: -frwpi Generate read-write position independent code (ARM only) -! CHECK-NEXT: -fsave-optimization-record= -! CHECK-NEXT: Generate an optimization record file in a specific format -! CHECK-NEXT: -fsave-optimization-record -! CHECK-NEXT: Generate a YAML optimization record file -! CHECK-NEXT: -fstack-arrays Attempt to allocate array temporaries on the stack, no matter their size -! CHECK-NEXT: -fsyntax-only Run the preprocessor, parser and semantic analysis stages -! CHECK-NEXT: -funderscoring Appends one trailing underscore to external names -! CHECK-NEXT: -fveclib= Use the given vector functions library -! CHECK-NEXT: -fversion-loops-for-stride -! CHECK-NEXT: Create unit-strided versions of loops -! CHECK-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV. -! CHECK-NEXT: --gcc-install-dir= -! CHECK-NEXT: Use GCC installation in the specified directory. The directory ends with path components like 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used by the compiler are not overridden by the selected GCC installation -! CHECK-NEXT: --gcc-toolchain= Specify a directory where Flang can find 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC installation with the largest version -! CHECK-NEXT: -gline-directives-only Emit debug line info directives only -! CHECK-NEXT: -gline-tables-only Emit debug line number tables only -! CHECK-NEXT: -gpulibc Link the LLVM C Library for GPUs -! CHECK-NEXT: -g Generate source-level debug information -! CHECK-NEXT: --help-hidden Display help for hidden options -! CHECK-NEXT: -help Display available options -! CHECK-NEXT: -isysroot Set the system root directory (usually /) -! CHECK-NEXT: -I Add directory to the end of the list of include search paths -! CHECK-NEXT: -L Add directory to library search path -! CHECK-NEXT: -march= For a list of available architectures for the target use '-mcpu=help' -! CHECK-NEXT: -mcode-object-version= -! CHECK-NEXT: Specify code object ABI version. Defaults to 5. (AMDGPU only) -! CHECK-NEXT: -mcpu= For a list of available CPUs for the target use '-mcpu=help' -! CHECK-NEXT: -mllvm= Alias for -mllvm -! CHECK-NEXT: -mllvm Additional arguments to forward to LLVM's option processing -! CHECK-NEXT: -mmlir Additional arguments to forward to MLIR's option processing -! CHECK-NEXT: -mno-outline-atomics Don't generate local calls to out-of-line atomic operations -! CHECK-NEXT: -module-dir Put MODULE files in -! CHECK-NEXT: -moutline-atomics Generate local calls to out-of-line atomic operations -! CHECK-NEXT: -mrvv-vector-bits= -! CHECK-NEXT: Specify the size in bits of an RVV vector register -! CHECK-NEXT: -msve-vector-bits= -! CHECK-NEXT: Specify the size in bits of an SVE vector register. Defaults to the vector length agnostic value of "scalable". (AArch64 only) -! CHECK-NEXT: --no-offload-arch= -! CHECK-NEXT: Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. 'all' resets the list to its default value. -! CHECK-NEXT: -nocpp Disable predefined and command line preprocessor macros -! CHECK-NEXT: -nogpulib Do not link device library for CUDA/HIP device compilation -! CHECK-NEXT: --offload-arch= Specify an offloading device architecture for CUDA, HIP, or OpenMP. (e.g. sm_35). If 'native' is used the compiler will detect locally installed architectures. For HIP offloading, the device architecture can be followed by target ID features delimited by a colon (e.g. gfx908:xnack+:sramecc-). May be specified more than once. -! CHECK-NEXT: --offload-device-only Only compile for the offloading device. -! CHECK-NEXT: --offload-host-device Compile for both the offloading host and device (default). -! CHECK-NEXT: --offload-host-only Only compile for the offloading host. -! CHECK-NEXT: -o Write output to -! CHECK-NEXT: -pedantic Warn on language extensions -! CHECK-NEXT: -print-effective-triple Print the effective target triple -! CHECK-NEXT: -print-target-triple Print the normalized target triple -! CHECK-NEXT: -pthread Support POSIX threads in generated code -! CHECK-NEXT: -P Disable linemarker output in -E mode -! CHECK-NEXT: -resource-dir The directory which holds the compiler resource files -! CHECK-NEXT: --rocm-path= ROCm installation path, used for finding and automatically linking required bitcode libraries. -! CHECK-NEXT: -Rpass-analysis= Report transformation analysis from optimization passes whose name matches the given POSIX regular expression -! CHECK-NEXT: -Rpass-missed= Report missed transformations by optimization passes whose name matches the given POSIX regular expression -! CHECK-NEXT: -Rpass= Report transformations performed by optimization passes whose name matches the given POSIX regular expression -! CHECK-NEXT: -R Enable the specified remark -! CHECK-NEXT: -save-temps= Save intermediate compilation results. -! CHECK-NEXT: -save-temps Alias for --save-temps=cwd -! CHECK-NEXT: -std= Language standard to compile for -! CHECK-NEXT: -S Only run preprocess and compilation steps -! CHECK-NEXT: --target= Generate code for the given target -! CHECK-NEXT: -U Undefine macro -! CHECK-NEXT: --version Print version information -! CHECK-NEXT: -v Show commands to run and use verbose output -! CHECK-NEXT: -Wl, Pass the comma separated arguments in to the linker -! CHECK-NEXT: -W Enable the specified warning -! CHECK-NEXT: -Xflang Pass to the flang compiler -! CHECK-NEXT: -x Treat subsequent input files as having type - - -! ERROR-FLANG: error: unknown argument '-help-hidden'; did you mean '--help-hidden'? - -! Frontend driver -help-hidden is not supported -! ERROR-FLANG-FC1: error: unknown argument: '{{.*}}' diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 index 0b0a493baf07..4c3609db80b9 100644 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -1,298 +1,15 @@ - -!-------------------------- -! FLANG DRIVER (flang) -!-------------------------- ! RUN: %flang -help 2>&1 | FileCheck %s --check-prefix=HELP ! RUN: not %flang -helps 2>&1 | FileCheck %s --check-prefix=ERROR -!---------------------------------------- -! FLANG FRONTEND DRIVER (flang -fc1) -!---------------------------------------- ! RUN: %flang_fc1 -help 2>&1 | FileCheck %s --check-prefix=HELP-FC1 ! RUN: not %flang_fc1 -helps 2>&1 | FileCheck %s --check-prefix=ERROR ! HELP:USAGE: flang ! HELP-EMPTY: ! HELP-NEXT:OPTIONS: -! HELP-NEXT: -### Print (but do not run) the commands to run for this compilation -! HELP-NEXT: -cpp Enable predefined and command line preprocessor macros -! HELP-NEXT: -c Only run preprocess, compile, and assemble steps -! HELP-NEXT: -dM Print macro definitions in -E mode instead of normal output -! HELP-NEXT: -dumpmachine Display the compiler's target processor -! HELP-NEXT: -dumpversion Display the version of the compiler -! HELP-NEXT: -D = Define to (or 1 if omitted) -! HELP-NEXT: -emit-llvm Use the LLVM representation for assembler and object files -! HELP-NEXT: -E Only run the preprocessor -! HELP-NEXT: -falternative-parameter-statement -! HELP-NEXT: Enable the old style PARAMETER statement -! HELP-NEXT: -fapprox-func Allow certain math function calls to be replaced with an approximately equivalent calculation -! HELP-NEXT: -fbackslash Specify that backslash in string introduces an escape character -! HELP-NEXT: -fcolor-diagnostics Enable colors in diagnostics -! HELP-NEXT: -fconvert= Set endian conversion of data for unformatted files -! HELP-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type -! HELP-NEXT: -fdefault-integer-8 Set the default integer and logical kind to an 8 byte wide type -! HELP-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type -! HELP-NEXT: -ffast-math Allow aggressive, lossy floating-point optimizations -! HELP-NEXT: -ffixed-form Process source files in fixed form -! HELP-NEXT: -ffixed-line-length= -! HELP-NEXT: Use as character line width in fixed mode -! HELP-NEXT: -ffp-contract= Form fused FP ops (e.g. FMAs) -! HELP-NEXT: -ffree-form Process source files in free form -! HELP-NEXT: -fhonor-infinities Specify that floating-point optimizations are not allowed that assume arguments and results are not +-inf. -! HELP-NEXT: -fhonor-nans Specify that floating-point optimizations are not allowed that assume arguments and results are not NANs. -! HELP-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements -! HELP-NEXT: -finput-charset= Specify the default character set for source files -! HELP-NEXT: -fintegrated-as Enable the integrated assembler -! HELP-NEXT: -fintrinsic-modules-path -! HELP-NEXT: Specify where to find the compiled intrinsic modules -! HELP-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics -! HELP-NEXT: -flogical-abbreviations Enable logical abbreviations -! HELP-NEXT: -flto=auto Enable LTO in 'full' mode -! HELP-NEXT: -flto=jobserver Enable LTO in 'full' mode -! HELP-NEXT: -flto= Set LTO mode -! HELP-NEXT: -flto Enable LTO in 'full' mode -! HELP-NEXT: -fms-runtime-lib= -! HELP-NEXT: Select Windows run-time library -! HELP-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE -! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics -! HELP-NEXT: -fno-fortran-main Do not include Fortran_main.a (provided by Flang) when linking -! HELP-NEXT: -fno-integrated-as Disable the integrated assembler -! HELP-NEXT: -fno-lto Disable LTO mode (default) -! HELP-NEXT: -fno-ppc-native-vector-element-order -! HELP-NEXT: Specifies PowerPC non-native vector element order -! HELP-NEXT: -fno-rtlib-add-rpath Do not add -rpath with architecture-specific resource directory to the linker flags. When --hip-link is specified, do not add -rpath with HIP runtime library directory to the linker flags -! HELP-NEXT: -fno-signed-zeros Allow optimizations that ignore the sign of floating point zeros -! HELP-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default) -! HELP-NEXT: -fno-version-loops-for-stride -! HELP-NEXT: Do not create unit-strided loops (default) -! HELP-NEXT: -fomit-frame-pointer Omit the frame pointer from functions that don't need it. Some stack unwinding cases, such as profilers and sanitizers, may prefer specifying -fno-omit-frame-pointer. On many targets, -O1 and higher omit the frame pointer by default. -m[no-]omit-leaf-frame-pointer takes precedence for leaf functions -! HELP-NEXT: -fopenacc Enable OpenACC -! HELP-NEXT: -fopenmp-target-debug Enable debugging in the OpenMP offloading device RTL -! HELP-NEXT: -fopenmp-targets= -! HELP-NEXT: Specify comma-separated list of triples OpenMP offloading targets to be supported -! HELP-NEXT: -fopenmp-version= -! HELP-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang -! HELP-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. -! HELP-NEXT: -foptimization-record-file= -! HELP-NEXT: Specify the output name of the file containing the optimization remarks. Implies -fsave-optimization-record. On Darwin platforms, this cannot be used with multiple -arch options. -! HELP-NEXT: -foptimization-record-passes= -! HELP-NEXT: Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes) -! HELP-NEXT: -fpass-plugin= Load pass plugin from a dynamic shared object file (only with new pass manager). -! HELP-NEXT: -fppc-native-vector-element-order -! HELP-NEXT: Specifies PowerPC native vector element order (default) -! HELP-NEXT: -freciprocal-math Allow division operations to be reassociated -! HELP-NEXT: -fropi Generate read-only position independent code (ARM only) -! HELP-NEXT: -frtlib-add-rpath Add -rpath with architecture-specific resource directory to the linker flags. When --hip-link is specified, also add -rpath with HIP runtime library directory to the linker flags -! HELP-NEXT: -frwpi Generate read-write position independent code (ARM only) -! HELP-NEXT: -fsave-optimization-record= -! HELP-NEXT: Generate an optimization record file in a specific format -! HELP-NEXT: -fsave-optimization-record -! HELP-NEXT: Generate a YAML optimization record file -! HELP-NEXT: -fstack-arrays Attempt to allocate array temporaries on the stack, no matter their size -! HELP-NEXT: -fsyntax-only Run the preprocessor, parser and semantic analysis stages -! HELP-NEXT: -funderscoring Appends one trailing underscore to external names -! HELP-NEXT: -fveclib= Use the given vector functions library -! HELP-NEXT: -fversion-loops-for-stride -! HELP-NEXT: Create unit-strided versions of loops -! HELP-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV. -! HELP-NEXT: --gcc-install-dir= -! HELP-NEXT: Use GCC installation in the specified directory. The directory ends with path components like 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used by the compiler are not overridden by the selected GCC installation -! HELP-NEXT: --gcc-toolchain= Specify a directory where Flang can find 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC installation with the largest version -! HELP-NEXT: -gline-directives-only Emit debug line info directives only -! HELP-NEXT: -gline-tables-only Emit debug line number tables only -! HELP-NEXT: -gpulibc Link the LLVM C Library for GPUs -! HELP-NEXT: -g Generate source-level debug information -! HELP-NEXT: --help-hidden Display help for hidden options -! HELP-NEXT: -help Display available options -! HELP-NEXT: -isysroot Set the system root directory (usually /) -! HELP-NEXT: -I Add directory to the end of the list of include search paths -! HELP-NEXT: -L Add directory to library search path -! HELP-NEXT: -march= For a list of available architectures for the target use '-mcpu=help' -! HELP-NEXT: -mcode-object-version= -! HELP-NEXT: Specify code object ABI version. Defaults to 5. (AMDGPU only) -! HELP-NEXT: -mcpu= For a list of available CPUs for the target use '-mcpu=help' -! HELP-NEXT: -mllvm= Alias for -mllvm -! HELP-NEXT: -mllvm Additional arguments to forward to LLVM's option processing -! HELP-NEXT: -mmlir Additional arguments to forward to MLIR's option processing -! HELP-NEXT: -mno-outline-atomics Don't generate local calls to out-of-line atomic operations -! HELP-NEXT: -module-dir Put MODULE files in -! HELP-NEXT: -moutline-atomics Generate local calls to out-of-line atomic operations -! HELP-NEXT: -mrvv-vector-bits= -! HELP-NEXT: Specify the size in bits of an RVV vector register -! HELP-NEXT: -msve-vector-bits= -! HELP-NEXT: Specify the size in bits of an SVE vector register. Defaults to the vector length agnostic value of "scalable". (AArch64 only) -! HELP-NEXT: --no-offload-arch= -! HELP-NEXT: Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. 'all' resets the list to its default value. -! HELP-NEXT: -nocpp Disable predefined and command line preprocessor macros -! HELP-NEXT: -nogpulib Do not link device library for CUDA/HIP device compilation -! HELP-NEXT: --offload-arch= Specify an offloading device architecture for CUDA, HIP, or OpenMP. (e.g. sm_35). If 'native' is used the compiler will detect locally installed architectures. For HIP offloading, the device architecture can be followed by target ID features delimited by a colon (e.g. gfx908:xnack+:sramecc-). May be specified more than once. -! HELP-NEXT: --offload-device-only Only compile for the offloading device. -! HELP-NEXT: --offload-host-device Compile for both the offloading host and device (default). -! HELP-NEXT: --offload-host-only Only compile for the offloading host. -! HELP-NEXT: -o Write output to -! HELP-NEXT: -pedantic Warn on language extensions -! HELP-NEXT: -print-effective-triple Print the effective target triple -! HELP-NEXT: -print-target-triple Print the normalized target triple -! HELP-NEXT: -pthread Support POSIX threads in generated code -! HELP-NEXT: -P Disable linemarker output in -E mode -! HELP-NEXT: --rocm-path= ROCm installation path, used for finding and automatically linking required bitcode libraries. -! HELP-NEXT: -Rpass-analysis= Report transformation analysis from optimization passes whose name matches the given POSIX regular expression -! HELP-NEXT: -Rpass-missed= Report missed transformations by optimization passes whose name matches the given POSIX regular expression -! HELP-NEXT: -Rpass= Report transformations performed by optimization passes whose name matches the given POSIX regular expression -! HELP-NEXT: -R Enable the specified remark -! HELP-NEXT: -save-temps= Save intermediate compilation results. -! HELP-NEXT: -save-temps Alias for --save-temps=cwd -! HELP-NEXT: -std= Language standard to compile for -! HELP-NEXT: -S Only run preprocess and compilation steps -! HELP-NEXT: --target= Generate code for the given target -! HELP-NEXT: -U Undefine macro -! HELP-NEXT: --version Print version information -! HELP-NEXT: -v Show commands to run and use verbose output -! HELP-NEXT: -Wl, Pass the comma separated arguments in to the linker -! HELP-NEXT: -W Enable the specified warning -! HELP-NEXT: -Xflang Pass to the flang compiler -! HELP-NEXT: -x Treat subsequent input files as having type - ! HELP-FC1:USAGE: flang ! HELP-FC1-EMPTY: ! HELP-FC1-NEXT:OPTIONS: -! HELP-FC1-NEXT: -cpp Enable predefined and command line preprocessor macros -! HELP-FC1-NEXT: --dependent-lib= Add dependent library -! HELP-FC1-NEXT: -dM Print macro definitions in -E mode instead of normal output -! HELP-FC1-NEXT: -D = Define to (or 1 if omitted) -! HELP-FC1-NEXT: -emit-fir Build the parse tree, then lower it to FIR -! HELP-FC1-NEXT: -emit-hlfir Build the parse tree, then lower it to HLFIR -! HELP-FC1-NEXT: -emit-llvm-bc Build ASTs then convert to LLVM, emit .bc file -! HELP-FC1-NEXT: -emit-llvm Use the LLVM representation for assembler and object files -! HELP-FC1-NEXT: -emit-obj Emit native object files -! HELP-FC1-NEXT: -E Only run the preprocessor -! HELP-FC1-NEXT: -falternative-parameter-statement -! HELP-FC1-NEXT: Enable the old style PARAMETER statement -! HELP-FC1-NEXT: -fapprox-func Allow certain math function calls to be replaced with an approximately equivalent calculation -! HELP-FC1-NEXT: -fbackslash Specify that backslash in string introduces an escape character -! HELP-FC1-NEXT: -fcolor-diagnostics Enable colors in diagnostics -! HELP-FC1-NEXT: -fconvert= Set endian conversion of data for unformatted files -! HELP-FC1-NEXT: -fdebug-dump-all Dump symbols and the parse tree after the semantic checks -! HELP-FC1-NEXT: -fdebug-dump-parse-tree-no-sema -! HELP-FC1-NEXT: Dump the parse tree (skips the semantic checks) -! HELP-FC1-NEXT: -fdebug-dump-parse-tree Dump the parse tree -! HELP-FC1-NEXT: -fdebug-dump-parsing-log -! HELP-FC1-NEXT: Run instrumented parse and dump the parsing log -! HELP-FC1-NEXT: -fdebug-dump-pft Dump the pre-fir parse tree -! HELP-FC1-NEXT: -fdebug-dump-provenance Dump provenance -! HELP-FC1-NEXT: -fdebug-dump-symbols Dump symbols after the semantic analysis -! HELP-FC1-NEXT: -fdebug-measure-parse-tree -! HELP-FC1-NEXT: Measure the parse tree -! HELP-FC1-NEXT: -fdebug-module-writer Enable debug messages while writing module files -! HELP-FC1-NEXT: -fdebug-pass-manager Prints debug information for the new pass manager -! HELP-FC1-NEXT: -fdebug-pre-fir-tree Dump the pre-FIR tree -! HELP-FC1-NEXT: -fdebug-unparse-no-sema Unparse and stop (skips the semantic checks) -! HELP-FC1-NEXT: -fdebug-unparse-with-symbols -! HELP-FC1-NEXT: Unparse and stop. -! HELP-FC1-NEXT: -fdebug-unparse Unparse and stop. -! HELP-FC1-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type -! HELP-FC1-NEXT: -fdefault-integer-8 Set the default integer and logical kind to an 8 byte wide type -! HELP-FC1-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type -! HELP-FC1-NEXT: -fembed-offload-object= -! HELP-FC1-NEXT: Embed Offloading device-side binary into host object file as a section. -! HELP-FC1-NEXT: -ffast-math Allow aggressive, lossy floating-point optimizations -! HELP-FC1-NEXT: -ffixed-form Process source files in fixed form -! HELP-FC1-NEXT: -ffixed-line-length= -! HELP-FC1-NEXT: Use as character line width in fixed mode -! HELP-FC1-NEXT: -ffp-contract= Form fused FP ops (e.g. FMAs) -! HELP-FC1-NEXT: -ffree-form Process source files in free form -! HELP-FC1-NEXT: -fget-definition -! HELP-FC1-NEXT: Get the symbol definition from -! HELP-FC1-NEXT: -fget-symbols-sources Dump symbols and their source code locations -! HELP-FC1-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements -! HELP-FC1-NEXT: -finput-charset= Specify the default character set for source files -! HELP-FC1-NEXT: -fintrinsic-modules-path -! HELP-FC1-NEXT: Specify where to find the compiled intrinsic modules -! HELP-FC1-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics -! HELP-FC1-NEXT: -flogical-abbreviations Enable logical abbreviations -! HELP-FC1-NEXT: -flto= Set LTO mode -! HELP-FC1-NEXT: -flto Enable LTO in 'full' mode -! HELP-FC1-NEXT: -fno-analyzed-objects-for-unparse -! HELP-FC1-NEXT: Do not use the analyzed objects when unparsing -! HELP-FC1-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE -! HELP-FC1-NEXT: -fno-debug-pass-manager Disables debug printing for the new pass manager -! HELP-FC1-NEXT: -fno-ppc-native-vector-element-order -! HELP-FC1-NEXT: Specifies PowerPC non-native vector element order -! HELP-FC1-NEXT: -fno-reformat Dump the cooked character stream in -E mode -! HELP-FC1-NEXT: -fno-signed-zeros Allow optimizations that ignore the sign of floating point zeros -! HELP-FC1-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default) -! HELP-FC1-NEXT: -fno-version-loops-for-stride -! HELP-FC1-NEXT: Do not create unit-strided loops (default) -! HELP-FC1-NEXT: -fopenacc Enable OpenACC -! HELP-FC1-NEXT: -fopenmp-host-ir-file-path -! HELP-FC1-NEXT: Path to the IR file produced by the frontend for the host. -! HELP-FC1-NEXT: -fopenmp-is-target-device -! HELP-FC1-NEXT: Generate code only for an OpenMP target device. -! HELP-FC1-NEXT: -fopenmp-target-debug Enable debugging in the OpenMP offloading device RTL -! HELP-FC1-NEXT: -fopenmp-version= -! HELP-FC1-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang -! HELP-FC1-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. -! HELP-FC1-NEXT: -fpass-plugin= Load pass plugin from a dynamic shared object file (only with new pass manager). -! HELP-FC1-NEXT: -fppc-native-vector-element-order -! HELP-FC1-NEXT: Specifies PowerPC native vector element order (default) -! HELP-FC1-NEXT: -freciprocal-math Allow division operations to be reassociated -! HELP-FC1-NEXT: -fstack-arrays Attempt to allocate array temporaries on the stack, no matter their size -! HELP-FC1-NEXT: -fsyntax-only Run the preprocessor, parser and semantic analysis stages -! HELP-FC1-NEXT: -funderscoring Appends one trailing underscore to external names -! HELP-FC1-NEXT: -fveclib= Use the given vector functions library -! HELP-FC1-NEXT: -fversion-loops-for-stride -! HELP-FC1-NEXT: Create unit-strided versions of loops -! HELP-FC1-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV. -! HELP-FC1-NEXT: -gpulibc Link the LLVM C Library for GPUs -! HELP-FC1-NEXT: -help Display available options -! HELP-FC1-NEXT: -init-only Only execute frontend initialization -! HELP-FC1-NEXT: -I Add directory to the end of the list of include search paths -! HELP-FC1-NEXT: -load Load the named plugin (dynamic shared object) -! HELP-FC1-NEXT: -mcode-object-version= -! HELP-FC1-NEXT: Specify code object ABI version. Defaults to 5. (AMDGPU only) -! HELP-FC1-NEXT: -menable-no-infs Allow optimization to assume there are no infinities. -! HELP-FC1-NEXT: -menable-no-nans Allow optimization to assume there are no NaNs. -! HELP-FC1-NEXT: -mframe-pointer= Specify which frame pointers to retain. -! HELP-FC1-NEXT: -mllvm Additional arguments to forward to LLVM's option processing -! HELP-FC1-NEXT: -mmlir Additional arguments to forward to MLIR's option processing -! HELP-FC1-NEXT: -module-dir Put MODULE files in -! HELP-FC1-NEXT: -module-suffix Use as the suffix for module files (the default value is `.mod`) -! HELP-FC1-NEXT: -mreassociate Allow reassociation transformations for floating-point instructions -! HELP-FC1-NEXT: -mrelocation-model -! HELP-FC1-NEXT: The relocation model to use -! HELP-FC1-NEXT: -mvscale-max= Specify the vscale maximum. Defaults to the vector length agnostic value of "0". (AArch64/RISC-V only) -! HELP-FC1-NEXT: -mvscale-min= Specify the vscale minimum. Defaults to "1". (AArch64/RISC-V only) -! HELP-FC1-NEXT: -nocpp Disable predefined and command line preprocessor macros -! HELP-FC1-NEXT: -nogpulib Do not link device library for CUDA/HIP device compilation -! HELP-FC1-NEXT: -opt-record-file -! HELP-FC1-NEXT: File name to use for YAML optimization record output -! HELP-FC1-NEXT: -opt-record-format -! HELP-FC1-NEXT: The format used for serializing remarks (default: YAML) -! HELP-FC1-NEXT: -opt-record-passes -! HELP-FC1-NEXT: Only record remark information for passes whose names match the given regular expression -! HELP-FC1-NEXT: -o Write output to -! HELP-FC1-NEXT: -pedantic Warn on language extensions -! HELP-FC1-NEXT: -pic-is-pie File is for a position independent executable -! HELP-FC1-NEXT: -pic-level Value for __PIC__ -! HELP-FC1-NEXT: -plugin Use the named plugin action instead of the default action (use "help" to list available options) -! HELP-FC1-NEXT: -pthread Support POSIX threads in generated code -! HELP-FC1-NEXT: -P Disable linemarker output in -E mode -! HELP-FC1-NEXT: -Rpass-analysis= Report transformation analysis from optimization passes whose name matches the given POSIX regular expression -! HELP-FC1-NEXT: -Rpass-missed= Report missed transformations by optimization passes whose name matches the given POSIX regular expression -! HELP-FC1-NEXT: -Rpass= Report transformations performed by optimization passes whose name matches the given POSIX regular expression -! HELP-FC1-NEXT: -R Enable the specified remark -! HELP-FC1-NEXT: -save-temps= Save intermediate compilation results. -! HELP-FC1-NEXT: -save-temps Alias for --save-temps=cwd -! HELP-FC1-NEXT: -std= Language standard to compile for -! HELP-FC1-NEXT: -S Only run preprocess and compilation steps -! HELP-FC1-NEXT: -target-cpu Target a specific cpu type -! HELP-FC1-NEXT: -target-feature Target specific attributes -! HELP-FC1-NEXT: -test-io Run the InputOuputTest action. Use for development and testing only. -! HELP-FC1-NEXT: -triple Specify target triple (e.g. i686-apple-darwin9) -! HELP-FC1-NEXT: -U Undefine macro -! HELP-FC1-NEXT: -version Print the compiler version -! HELP-FC1-NEXT: -W Enable the specified warning -! HELP-FC1-NEXT: -x Treat subsequent input files as having type ! ERROR: error: unknown argument '-helps'; did you mean '-help' -- GitLab From 2575cd8a900283368e451cdbc27a2e4db0722af9 Mon Sep 17 00:00:00 2001 From: Andy Kaylor Date: Wed, 24 Apr 2024 11:55:17 -0700 Subject: [PATCH 004/733] Add ics link for Floating Point WG (#82545) This adds a link to an ics file for the LLVM Floating Point WG line in the Getting Involved page. --- llvm/docs/GettingInvolved.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/docs/GettingInvolved.rst b/llvm/docs/GettingInvolved.rst index a4247796cb65..93be3bd1d854 100644 --- a/llvm/docs/GettingInvolved.rst +++ b/llvm/docs/GettingInvolved.rst @@ -228,7 +228,8 @@ what to add to your calendar invite. - `Meeting details/agenda `__ * - Floating Point Working Group - Every 3rd Wednesday of the month - - `gcal `__ + - `ics `__ + `gcal `__ - `Meeting details/agenda: `__ .. _office-hours: -- GitLab From 57794835279669358ff2828d659eb7133fc0e4bf Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Wed, 24 Apr 2024 12:13:18 -0700 Subject: [PATCH 005/733] [lldb][nfc] Move broadcaster class strings away from ConstString (#89690) These are hardcoded strings that are already present in the data section of the binary, no need to immediately place them in the ConstString StringPools. Lots of code still calls `GetBroadcasterClass` and places the return value into a ConstString. Changing that would be a good follow-up. Additionally, calls to these functions are still wrapped in ConstStrings at the SBAPI layer. This is because we must guarantee the lifetime of all strings handed out publicly. --- lldb/include/lldb/Core/Debugger.h | 2 +- lldb/include/lldb/Core/ThreadedCommunication.h | 4 ++-- lldb/include/lldb/Interpreter/CommandInterpreter.h | 4 ++-- lldb/include/lldb/Target/Process.h | 4 ++-- lldb/include/lldb/Target/Target.h | 4 ++-- lldb/include/lldb/Target/TargetList.h | 4 ++-- lldb/include/lldb/Target/Thread.h | 4 ++-- lldb/include/lldb/Utility/Broadcaster.h | 8 ++++---- lldb/source/API/SBCommandInterpreter.cpp | 3 ++- lldb/source/API/SBCommunication.cpp | 3 ++- lldb/source/API/SBDebugger.cpp | 2 +- lldb/source/API/SBEvent.cpp | 3 ++- lldb/source/API/SBProcess.cpp | 4 ++-- lldb/source/API/SBTarget.cpp | 2 +- lldb/source/API/SBThread.cpp | 2 +- lldb/source/Core/Debugger.cpp | 6 +++--- lldb/source/Core/ThreadedCommunication.cpp | 4 ++-- lldb/source/Interpreter/CommandInterpreter.cpp | 6 +++--- lldb/source/Target/Process.cpp | 6 +++--- lldb/source/Target/Target.cpp | 6 +++--- lldb/source/Target/TargetList.cpp | 6 +++--- lldb/source/Target/Thread.cpp | 6 +++--- lldb/source/Utility/Broadcaster.cpp | 4 ++-- 23 files changed, 50 insertions(+), 47 deletions(-) diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 418c2403d020..49ff0737acef 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -89,7 +89,7 @@ public: using DebuggerList = std::vector; - static ConstString GetStaticBroadcasterClass(); + static llvm::StringRef GetStaticBroadcasterClass(); /// Get the public broadcaster for this debugger. Broadcaster &GetBroadcaster() { return m_broadcaster; } diff --git a/lldb/include/lldb/Core/ThreadedCommunication.h b/lldb/include/lldb/Core/ThreadedCommunication.h index 7ebb77beb77f..24412b202793 100644 --- a/lldb/include/lldb/Core/ThreadedCommunication.h +++ b/lldb/include/lldb/Core/ThreadedCommunication.h @@ -216,9 +216,9 @@ public: /// void SynchronizeWithReadThread(); - static ConstString &GetStaticBroadcasterClass(); + static llvm::StringRef GetStaticBroadcasterClass(); - ConstString &GetBroadcasterClass() const override { + llvm::StringRef GetBroadcasterClass() const override { return GetStaticBroadcasterClass(); } diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h index d190bcdcab44..70a55a77465b 100644 --- a/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -255,9 +255,9 @@ public: // These two functions fill out the Broadcaster interface: - static ConstString &GetStaticBroadcasterClass(); + static llvm::StringRef GetStaticBroadcasterClass(); - ConstString &GetBroadcasterClass() const override { + llvm::StringRef GetBroadcasterClass() const override { return GetStaticBroadcasterClass(); } diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 2f3a3c22422e..aac0cf51680a 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -381,7 +381,7 @@ public: // These two functions fill out the Broadcaster interface: - static ConstString &GetStaticBroadcasterClass(); + static llvm::StringRef GetStaticBroadcasterClass(); static constexpr llvm::StringRef AttachSynchronousHijackListenerName = "lldb.internal.Process.AttachSynchronous.hijack"; @@ -390,7 +390,7 @@ public: static constexpr llvm::StringRef ResumeSynchronousHijackListenerName = "lldb.internal.Process.ResumeSynchronous.hijack"; - ConstString &GetBroadcasterClass() const override { + llvm::StringRef GetBroadcasterClass() const override { return GetStaticBroadcasterClass(); } diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 2c2e6b2831cc..cade60f3cc8c 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -499,9 +499,9 @@ public: // These two functions fill out the Broadcaster interface: - static ConstString &GetStaticBroadcasterClass(); + static llvm::StringRef GetStaticBroadcasterClass(); - ConstString &GetBroadcasterClass() const override { + llvm::StringRef GetBroadcasterClass() const override { return GetStaticBroadcasterClass(); } diff --git a/lldb/include/lldb/Target/TargetList.h b/lldb/include/lldb/Target/TargetList.h index a0bc6f1f820b..a0cddc6b2966 100644 --- a/lldb/include/lldb/Target/TargetList.h +++ b/lldb/include/lldb/Target/TargetList.h @@ -37,9 +37,9 @@ public: // These two functions fill out the Broadcaster interface: - static ConstString &GetStaticBroadcasterClass(); + static llvm::StringRef GetStaticBroadcasterClass(); - ConstString &GetBroadcasterClass() const override { + llvm::StringRef GetBroadcasterClass() const override { return GetStaticBroadcasterClass(); } diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index 1efef93b17de..c17bddf4d98b 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -74,9 +74,9 @@ public: eBroadcastBitThreadSelected = (1 << 4) }; - static ConstString &GetStaticBroadcasterClass(); + static llvm::StringRef GetStaticBroadcasterClass(); - ConstString &GetBroadcasterClass() const override { + llvm::StringRef GetBroadcasterClass() const override { return GetStaticBroadcasterClass(); } diff --git a/lldb/include/lldb/Utility/Broadcaster.h b/lldb/include/lldb/Utility/Broadcaster.h index f39e677fe9ee..58436ddb9f26 100644 --- a/lldb/include/lldb/Utility/Broadcaster.h +++ b/lldb/include/lldb/Utility/Broadcaster.h @@ -39,12 +39,12 @@ namespace lldb_private { /// Debugger maintains a list of BroadcastEventSpec's and when it is made class BroadcastEventSpec { public: - BroadcastEventSpec(const ConstString &broadcaster_class, uint32_t event_bits) + BroadcastEventSpec(llvm::StringRef broadcaster_class, uint32_t event_bits) : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {} ~BroadcastEventSpec() = default; - ConstString GetBroadcasterClass() const { return m_broadcaster_class; } + const std::string &GetBroadcasterClass() const { return m_broadcaster_class; } uint32_t GetEventBits() const { return m_event_bits; } @@ -67,7 +67,7 @@ public: bool operator<(const BroadcastEventSpec &rhs) const; private: - ConstString m_broadcaster_class; + std::string m_broadcaster_class; uint32_t m_event_bits; }; @@ -307,7 +307,7 @@ public: /// FIXME: Probably should make a ManagedBroadcaster subclass with all the /// bits needed to work with the BroadcasterManager, so that it is clearer /// how to add one. - virtual ConstString &GetBroadcasterClass() const; + virtual llvm::StringRef GetBroadcasterClass() const; lldb::BroadcasterManagerSP GetManager(); diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index 7b87dc507e4b..83c0951c56db 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -512,7 +512,8 @@ SBBroadcaster SBCommandInterpreter::GetBroadcaster() { const char *SBCommandInterpreter::GetBroadcasterClass() { LLDB_INSTRUMENT(); - return CommandInterpreter::GetStaticBroadcasterClass().AsCString(); + return ConstString(CommandInterpreter::GetStaticBroadcasterClass()) + .AsCString(); } const char *SBCommandInterpreter::GetArgumentTypeAsCString( diff --git a/lldb/source/API/SBCommunication.cpp b/lldb/source/API/SBCommunication.cpp index f93898718be6..ee33e2abd854 100644 --- a/lldb/source/API/SBCommunication.cpp +++ b/lldb/source/API/SBCommunication.cpp @@ -170,5 +170,6 @@ SBBroadcaster SBCommunication::GetBroadcaster() { const char *SBCommunication::GetBroadcasterClass() { LLDB_INSTRUMENT(); - return ThreadedCommunication::GetStaticBroadcasterClass().AsCString(); + return ConstString(ThreadedCommunication::GetStaticBroadcasterClass()) + .AsCString(); } diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index fbcf30e67fc1..9c662dfbf441 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -112,7 +112,7 @@ SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) { const char *SBDebugger::GetBroadcasterClass() { LLDB_INSTRUMENT(); - return Debugger::GetStaticBroadcasterClass().AsCString(); + return ConstString(Debugger::GetStaticBroadcasterClass()).AsCString(); } const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event, diff --git a/lldb/source/API/SBEvent.cpp b/lldb/source/API/SBEvent.cpp index cc611449e250..aa9c0ff097d4 100644 --- a/lldb/source/API/SBEvent.cpp +++ b/lldb/source/API/SBEvent.cpp @@ -95,7 +95,8 @@ const char *SBEvent::GetBroadcasterClass() const { const Event *lldb_event = get(); if (lldb_event) - return lldb_event->GetBroadcaster()->GetBroadcasterClass().AsCString(); + return ConstString(lldb_event->GetBroadcaster()->GetBroadcasterClass()) + .AsCString(); else return "unknown class"; } diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index b80664882ebc..c73348fde3f7 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -77,7 +77,7 @@ SBProcess::~SBProcess() = default; const char *SBProcess::GetBroadcasterClassName() { LLDB_INSTRUMENT(); - return Process::GetStaticBroadcasterClass().AsCString(); + return ConstString(Process::GetStaticBroadcasterClass()).AsCString(); } const char *SBProcess::GetPluginName() { @@ -807,7 +807,7 @@ SBBroadcaster SBProcess::GetBroadcaster() const { const char *SBProcess::GetBroadcasterClass() { LLDB_INSTRUMENT(); - return Process::GetStaticBroadcasterClass().AsCString(); + return ConstString(Process::GetStaticBroadcasterClass()).AsCString(); } size_t SBProcess::ReadMemory(addr_t addr, void *dst, size_t dst_len, diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index cc9f1fdd76af..75f0444f6291 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -147,7 +147,7 @@ SBModule SBTarget::GetModuleAtIndexFromEvent(const uint32_t idx, const char *SBTarget::GetBroadcasterClassName() { LLDB_INSTRUMENT(); - return Target::GetStaticBroadcasterClass().AsCString(); + return ConstString(Target::GetStaticBroadcasterClass()).AsCString(); } bool SBTarget::IsValid() const { diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index eb9cf063802c..ac3e2cd25daa 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -53,7 +53,7 @@ using namespace lldb_private; const char *SBThread::GetBroadcasterClassName() { LLDB_INSTRUMENT(); - return Thread::GetStaticBroadcasterClass().AsCString(); + return ConstString(Thread::GetStaticBroadcasterClass()).AsCString(); } // Constructors diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 19b3cf3bbf46..cac4642873b7 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -823,8 +823,8 @@ TargetSP Debugger::FindTargetWithProcess(Process *process) { return target_sp; } -ConstString Debugger::GetStaticBroadcasterClass() { - static ConstString class_name("lldb.debugger"); +llvm::StringRef Debugger::GetStaticBroadcasterClass() { + static constexpr llvm::StringLiteral class_name("lldb.debugger"); return class_name; } @@ -846,7 +846,7 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(), m_sync_broadcaster(nullptr, "lldb.debugger.sync"), m_broadcaster(m_broadcaster_manager_sp, - GetStaticBroadcasterClass().AsCString()), + GetStaticBroadcasterClass().str()), m_forward_listener_sp(), m_clear_once() { // Initialize the debugger properties as early as possible as other parts of // LLDB will start querying them during construction. diff --git a/lldb/source/Core/ThreadedCommunication.cpp b/lldb/source/Core/ThreadedCommunication.cpp index 7d8aae5d8ff6..2f3dada3ac93 100644 --- a/lldb/source/Core/ThreadedCommunication.cpp +++ b/lldb/source/Core/ThreadedCommunication.cpp @@ -32,8 +32,8 @@ using namespace lldb; using namespace lldb_private; -ConstString &ThreadedCommunication::GetStaticBroadcasterClass() { - static ConstString class_name("lldb.communication"); +llvm::StringRef ThreadedCommunication::GetStaticBroadcasterClass() { + static constexpr llvm::StringLiteral class_name("lldb.communication"); return class_name; } diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 8c3972a2ba4c..4c58ecc3c184 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -119,15 +119,15 @@ enum { #include "InterpreterPropertiesEnum.inc" }; -ConstString &CommandInterpreter::GetStaticBroadcasterClass() { - static ConstString class_name("lldb.commandInterpreter"); +llvm::StringRef CommandInterpreter::GetStaticBroadcasterClass() { + static constexpr llvm::StringLiteral class_name("lldb.commandInterpreter"); return class_name; } CommandInterpreter::CommandInterpreter(Debugger &debugger, bool synchronous_execution) : Broadcaster(debugger.GetBroadcasterManager(), - CommandInterpreter::GetStaticBroadcasterClass().AsCString()), + CommandInterpreter::GetStaticBroadcasterClass().str()), Properties( OptionValuePropertiesSP(new OptionValueProperties("interpreter"))), IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand), diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 606518ca5412..30c240b064b5 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -408,8 +408,8 @@ ProcessSP Process::FindPlugin(lldb::TargetSP target_sp, return process_sp; } -ConstString &Process::GetStaticBroadcasterClass() { - static ConstString class_name("lldb.process"); +llvm::StringRef Process::GetStaticBroadcasterClass() { + static constexpr llvm::StringLiteral class_name("lldb.process"); return class_name; } @@ -423,7 +423,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, const UnixSignalsSP &unix_signals_sp) : ProcessProperties(this), Broadcaster((target_sp->GetDebugger().GetBroadcasterManager()), - Process::GetStaticBroadcasterClass().AsCString()), + Process::GetStaticBroadcasterClass().str()), m_target_wp(target_sp), m_public_state(eStateUnloaded), m_private_state(eStateUnloaded), m_private_state_broadcaster(nullptr, diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 09b0ac42631d..aa4895bb5a6d 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -87,8 +87,8 @@ const Target::Arch &Target::Arch::operator=(const ArchSpec &spec) { return *this; } -ConstString &Target::GetStaticBroadcasterClass() { - static ConstString class_name("lldb.target"); +llvm::StringRef Target::GetStaticBroadcasterClass() { + static constexpr llvm::StringLiteral class_name("lldb.target"); return class_name; } @@ -96,7 +96,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp, bool is_dummy_target) : TargetProperties(this), Broadcaster(debugger.GetBroadcasterManager(), - Target::GetStaticBroadcasterClass().AsCString()), + Target::GetStaticBroadcasterClass().str()), ExecutionContextScope(), m_debugger(debugger), m_platform_sp(platform_sp), m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(), m_breakpoint_list(false), m_internal_breakpoint_list(true), diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp index b5d308739d0f..10467753666f 100644 --- a/lldb/source/Target/TargetList.cpp +++ b/lldb/source/Target/TargetList.cpp @@ -29,15 +29,15 @@ using namespace lldb; using namespace lldb_private; -ConstString &TargetList::GetStaticBroadcasterClass() { - static ConstString class_name("lldb.targetList"); +llvm::StringRef TargetList::GetStaticBroadcasterClass() { + static constexpr llvm::StringLiteral class_name("lldb.targetList"); return class_name; } // TargetList constructor TargetList::TargetList(Debugger &debugger) : Broadcaster(debugger.GetBroadcasterManager(), - TargetList::GetStaticBroadcasterClass().AsCString()), + TargetList::GetStaticBroadcasterClass().str()), m_target_list(), m_target_list_mutex(), m_selected_target_idx(0) { CheckInWithManager(); } diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 412e44ede9c1..e75f5a356cec 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -205,15 +205,15 @@ Thread::ThreadEventData::GetStackFrameFromEvent(const Event *event_ptr) { // Thread class -ConstString &Thread::GetStaticBroadcasterClass() { - static ConstString class_name("lldb.thread"); +llvm::StringRef Thread::GetStaticBroadcasterClass() { + static constexpr llvm::StringLiteral class_name("lldb.thread"); return class_name; } Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id) : ThreadProperties(false), UserID(tid), Broadcaster(process.GetTarget().GetDebugger().GetBroadcasterManager(), - Thread::GetStaticBroadcasterClass().AsCString()), + Thread::GetStaticBroadcasterClass().str()), m_process_wp(process.shared_from_this()), m_stop_info_sp(), m_stop_info_stop_id(0), m_stop_info_override_stop_id(0), m_should_run_before_public_stop(false), diff --git a/lldb/source/Utility/Broadcaster.cpp b/lldb/source/Utility/Broadcaster.cpp index 12903edc36b1..bd65ffd86a1d 100644 --- a/lldb/source/Utility/Broadcaster.cpp +++ b/lldb/source/Utility/Broadcaster.cpp @@ -373,8 +373,8 @@ void Broadcaster::BroadcasterImpl::RestoreBroadcaster() { m_hijacking_masks.pop_back(); } -ConstString &Broadcaster::GetBroadcasterClass() const { - static ConstString class_name("lldb.anonymous"); +llvm::StringRef Broadcaster::GetBroadcasterClass() const { + static constexpr llvm::StringLiteral class_name("lldb.anonymous"); return class_name; } -- GitLab From 37e13d4924841bd84edb8c67c667d6d2a6c2bc63 Mon Sep 17 00:00:00 2001 From: Brian Gesiak Date: Wed, 24 Apr 2024 15:14:38 -0400 Subject: [PATCH 006/733] [mlir-lsp] Log invalid notification params (#89856) When the `lsp::MessageHandler` processes a request with invalid params (that is, the "params" JSON sent along with the request does not match the shape expected by the message handler for the given method), it replies by sending an error response to the client. On the other hand, the language server protocol specifies that notifications must not result in responses. As a result, when the JSON params accompanying a notification cannot be parsed, no error is sent back; there is no indication that an error has occurred at all. This patch adds an error log for that case. Although clients cannot parse error logs, this at least provides an indication that something went wrong on the language server side. --- .../mlir/Tools/lsp-server-support/Transport.h | 12 +- .../Tools/lsp-server-support/Transport.cpp | 106 +++++++++++++----- 2 files changed, 90 insertions(+), 28 deletions(-) diff --git a/mlir/include/mlir/Tools/lsp-server-support/Transport.h b/mlir/include/mlir/Tools/lsp-server-support/Transport.h index ce742be7a941..44c71058cf71 100644 --- a/mlir/include/mlir/Tools/lsp-server-support/Transport.h +++ b/mlir/include/mlir/Tools/lsp-server-support/Transport.h @@ -147,9 +147,15 @@ public: void (ThisT::*handler)(const Param &)) { notificationHandlers[method] = [method, handler, thisPtr](llvm::json::Value rawParams) { - llvm::Expected param = parse(rawParams, method, "request"); - if (!param) - return llvm::consumeError(param.takeError()); + llvm::Expected param = + parse(rawParams, method, "notification"); + if (!param) { + return llvm::consumeError( + llvm::handleErrors(param.takeError(), [](const LSPError &lspError) { + Logger::error("JSON parsing error: {0}", + lspError.message.c_str()); + })); + } (thisPtr->*handler)(*param); }; } diff --git a/mlir/unittests/Tools/lsp-server-support/Transport.cpp b/mlir/unittests/Tools/lsp-server-support/Transport.cpp index 9877c12c3695..48eae32a0fc3 100644 --- a/mlir/unittests/Tools/lsp-server-support/Transport.cpp +++ b/mlir/unittests/Tools/lsp-server-support/Transport.cpp @@ -7,7 +7,8 @@ //===----------------------------------------------------------------------===// #include "mlir/Tools/lsp-server-support/Transport.h" -#include "llvm/ADT/ScopeExit.h" +#include "mlir/Tools/lsp-server-support/Logging.h" +#include "mlir/Tools/lsp-server-support/Protocol.h" #include "llvm/Support/FileSystem.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -29,37 +30,92 @@ TEST(TransportTest, SendReply) { EXPECT_THAT(out, HasSubstr("\"result\":null")); } -TEST(TransportTest, MethodNotFound) { - auto tempOr = llvm::sys::fs::TempFile::create("lsp-unittest-%%%%%%.json"); - ASSERT_TRUE((bool)tempOr); - auto discardTemp = - llvm::make_scope_exit([&]() { ASSERT_FALSE((bool)tempOr->discard()); }); +class TransportInputTest : public Test { + std::optional inputTempFile; + std::FILE *in = nullptr; + std::string output = ""; + llvm::raw_string_ostream os; + std::optional transport = std::nullopt; + std::optional messageHandler = std::nullopt; - { +protected: + TransportInputTest() : os(output) {} + + void SetUp() override { + auto tempOr = llvm::sys::fs::TempFile::create("lsp-unittest-%%%%%%.json"); + ASSERT_TRUE((bool)tempOr); + llvm::sys::fs::TempFile t = std::move(*tempOr); + inputTempFile = std::move(t); + + in = std::fopen(inputTempFile->TmpName.c_str(), "r"); + transport.emplace(in, os, JSONStreamStyle::Delimited); + messageHandler.emplace(*transport); + } + + void TearDown() override { + EXPECT_FALSE(inputTempFile->discard()); + EXPECT_EQ(std::fclose(in), 0); + } + + void writeInput(StringRef buffer) { std::error_code ec; - llvm::raw_fd_ostream os(tempOr->TmpName, ec); + llvm::raw_fd_ostream os(inputTempFile->TmpName, ec); ASSERT_FALSE(ec); - os << "{\"jsonrpc\":\"2.0\",\"id\":29,\"method\":\"ack\"}\n"; + os << buffer; os.close(); } - std::string out; - llvm::raw_string_ostream os(out); - std::FILE *in = std::fopen(tempOr->TmpName.c_str(), "r"); - auto closeIn = llvm::make_scope_exit([&]() { std::fclose(in); }); + StringRef getOutput() const { return output; } + MessageHandler &getMessageHandler() { return *messageHandler; } - JSONTransport transport(in, os, JSONStreamStyle::Delimited); - MessageHandler handler(transport); + void runTransport() { + bool gotEOF = false; + llvm::Error err = llvm::handleErrors( + transport->run(*messageHandler), [&](const llvm::ECError &ecErr) { + gotEOF = ecErr.convertToErrorCode() == std::errc::io_error; + }); + llvm::consumeError(std::move(err)); + EXPECT_TRUE(gotEOF); + } +}; + +TEST_F(TransportInputTest, RequestWithInvalidParams) { + struct Handler { + void onMethod(const TextDocumentItem ¶ms, + mlir::lsp::Callback callback) {} + } handler; + getMessageHandler().method("invalid-params-request", &handler, + &Handler::onMethod); + + writeInput("{\"jsonrpc\":\"2.0\",\"id\":92," + "\"method\":\"invalid-params-request\",\"params\":{}}\n"); + runTransport(); + EXPECT_THAT(getOutput(), HasSubstr("error")); + EXPECT_THAT(getOutput(), HasSubstr("missing value at (root).uri")); +} + +TEST_F(TransportInputTest, NotificationWithInvalidParams) { + // JSON parsing errors are only reported via error logging. As a result, this + // test can't make any expectations -- but it prints the output anyway, by way + // of demonstration. + Logger::setLogLevel(Logger::Level::Error); + + struct Handler { + void onNotification(const TextDocumentItem ¶ms) {} + } handler; + getMessageHandler().notification("invalid-params-notification", &handler, + &Handler::onNotification); + + writeInput("{\"jsonrpc\":\"2.0\",\"method\":\"invalid-params-notification\"," + "\"params\":{}}\n"); + runTransport(); +} - bool gotEOF = false; - llvm::Error err = llvm::handleErrors( - transport.run(handler), [&](const llvm::ECError &ecErr) { - gotEOF = ecErr.convertToErrorCode() == std::errc::io_error; - }); - llvm::consumeError(std::move(err)); - EXPECT_TRUE(gotEOF); - EXPECT_THAT(out, HasSubstr("\"id\":29")); - EXPECT_THAT(out, HasSubstr("\"error\"")); - EXPECT_THAT(out, HasSubstr("\"message\":\"method not found: ack\"")); +TEST_F(TransportInputTest, MethodNotFound) { + writeInput("{\"jsonrpc\":\"2.0\",\"id\":29,\"method\":\"ack\"}\n"); + runTransport(); + EXPECT_THAT(getOutput(), HasSubstr("\"id\":29")); + EXPECT_THAT(getOutput(), HasSubstr("\"error\"")); + EXPECT_THAT(getOutput(), HasSubstr("\"message\":\"method not found: ack\"")); } } // namespace -- GitLab From 791161516f48f41ae90f1231fdfc7374f43b5a9f Mon Sep 17 00:00:00 2001 From: Frederic Cambus Date: Wed, 24 Apr 2024 21:18:24 +0200 Subject: [PATCH 007/733] [compiler-rt] Update libFuzzer build script to use C++17. (#89604) libFuzzer uses std::clamp which was introduced in C++17. --- compiler-rt/lib/fuzzer/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/lib/fuzzer/build.sh b/compiler-rt/lib/fuzzer/build.sh index f7f329c0d19c..f58fd9557ce3 100755 --- a/compiler-rt/lib/fuzzer/build.sh +++ b/compiler-rt/lib/fuzzer/build.sh @@ -2,7 +2,7 @@ LIBFUZZER_SRC_DIR=$(dirname $0) CXX="${CXX:-clang}" for f in $LIBFUZZER_SRC_DIR/*.cpp; do - $CXX -g -O2 -fno-omit-frame-pointer -std=c++14 $f -c & + $CXX -g -O2 -fno-omit-frame-pointer -std=c++17 $f -c & done wait rm -f libFuzzer.a -- GitLab From 03bb10dfb3725ec2c31fb66deede96d066f2b49a Mon Sep 17 00:00:00 2001 From: Chao Chen <116223022+chencha3@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:29:11 -0500 Subject: [PATCH 008/733] [MLIR][XeGPU] Add dpas, atomic, and named barrier ops (#88973) --------- Co-authored-by: Mehdi Amini Co-authored-by: Adam Siemieniuk --- .../mlir/Dialect/XeGPU/IR/CMakeLists.txt | 6 +- mlir/include/mlir/Dialect/XeGPU/IR/XeGPU.h | 3 +- .../mlir/Dialect/XeGPU/IR/XeGPUAttrs.td | 18 ++ .../mlir/Dialect/XeGPU/IR/XeGPUDialect.td | 4 +- .../include/mlir/Dialect/XeGPU/IR/XeGPUOps.td | 159 +++++++++++++++++- .../mlir/Dialect/XeGPU/IR/XeGPUTypes.td | 11 ++ mlir/lib/Dialect/XeGPU/IR/XeGPUOps.cpp | 22 +++ mlir/test/Dialect/XeGPU/XeGPUOps.mlir | 59 ++++++- mlir/test/Dialect/XeGPU/invalid.mlir | 28 +++ 9 files changed, 296 insertions(+), 14 deletions(-) diff --git a/mlir/include/mlir/Dialect/XeGPU/IR/CMakeLists.txt b/mlir/include/mlir/Dialect/XeGPU/IR/CMakeLists.txt index f1740e9ed929..3f8cac4dc07c 100644 --- a/mlir/include/mlir/Dialect/XeGPU/IR/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/XeGPU/IR/CMakeLists.txt @@ -2,12 +2,12 @@ add_mlir_dialect(XeGPU xegpu) add_mlir_doc(XeGPU XeGPU Dialects/ -gen-dialect-doc -dialect=xegpu) set(LLVM_TARGET_DEFINITIONS XeGPU.td) -mlir_tablegen(XeGPUAttrs.h.inc -gen-attrdef-decls) -mlir_tablegen(XeGPUAttrs.cpp.inc -gen-attrdef-defs) +mlir_tablegen(XeGPUAttrs.h.inc -gen-attrdef-decls -attrdefs-dialect=xegpu) +mlir_tablegen(XeGPUAttrs.cpp.inc -gen-attrdef-defs -attrdefs-dialect=xegpu) add_public_tablegen_target(MLIRXeGPUAttrsIncGen) add_dependencies(mlir-headers MLIRXeGPUAttrsIncGen) -set(LLVM_TARGET_DEFINITIONS XeGPU.td) +set(LLVM_TARGET_DEFINITIONS XeGPUAttrs.td) mlir_tablegen(XeGPUEnums.h.inc -gen-enum-decls) mlir_tablegen(XeGPUEnums.cpp.inc -gen-enum-defs) add_public_tablegen_target(MLIRXeGPUEnumsIncGen) diff --git a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPU.h b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPU.h index eca9255ff397..7ac0cf77fe59 100644 --- a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPU.h +++ b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPU.h @@ -10,6 +10,7 @@ #define MLIR_DIALECT_XEGPU_IR_XEGPU_H #include "mlir/Bytecode/BytecodeOpInterface.h" +#include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/Dialect.h" #include "mlir/IR/TypeUtilities.h" @@ -19,7 +20,7 @@ namespace mlir { namespace xegpu { -// placeholder +class TensorDescType; } // namespace xegpu } // namespace mlir diff --git a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUAttrs.td b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUAttrs.td index 6579d07ec262..f3ca09a6a68e 100644 --- a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUAttrs.td +++ b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUAttrs.td @@ -10,6 +10,7 @@ #define MLIR_DIALECT_XEGPU_IR_XEGPUATTRS_TD include "mlir/Dialect/XeGPU/IR/XeGPUDialect.td" +include "mlir/IR/AttrTypeBase.td" include "mlir/IR/EnumAttr.td" class XeGPUAttr traits = [], @@ -98,4 +99,21 @@ def XeGPU_CacheHintAttr let assemblyFormat = "`<` $value `>`"; } +def XeGPU_FenceScopeWorkgroup: I32EnumAttrCase<"Workgroup", 0, "workgroup">; +def XeGPU_FenceScopeGPU: I32EnumAttrCase<"GPU", 1, "gpu">; +def XeGPU_FenceScope: I32EnumAttr<"FenceScope", + "The enumeration for the scope of fence operation.", + [XeGPU_FenceScopeWorkgroup, XeGPU_FenceScopeGPU]> { + let genSpecializedAttr = 0; + let cppNamespace = "::mlir::xegpu"; +} + +def XeGPU_FenceScopeAttr: + EnumAttr { + let summary = [{Describes the scope of fence. + "workgroup" means that the scope is within each work group. + "gpu" means the scope is across work groups within the gpu.}]; + let assemblyFormat = "$value"; +} + #endif // MLIR_DIALECT_XEGPU_IR_XEGPUATTRS_TD \ No newline at end of file diff --git a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUDialect.td b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUDialect.td index c2f09319c790..765f218f95d2 100644 --- a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUDialect.td +++ b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUDialect.td @@ -17,12 +17,14 @@ def XeGPU_Dialect : Dialect { let summary = "The XeGPU dialect that models Intel GPU's ISA"; let description = [{ The XeGPU dialect models Intel Xe ISA semantics but works at vector and - TensorDesc data type. It provides 1:1 mappings to match Xe instructions + TensorDesc data type. It provides 1:1 mappings to match Xe instructions like DPAS and 2D block load. The matrix size being processed at this level exactly matches the hardware instructions or the intrinsic supported by the lower-level GPU compiler. }]; + let dependentDialects = ["arith::ArithDialect"]; + let useDefaultTypePrinterParser = true; let useDefaultAttributePrinterParser = true; } diff --git a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td index c6f7f83441b9..88f2e1acfeeb 100644 --- a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td +++ b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td @@ -9,7 +9,7 @@ #ifndef MLIR_DIALECT_XEGPU_IR_XEGPUOPS_TD #define MLIR_DIALECT_XEGPU_IR_XEGPUOPS_TD -include "mlir/IR/AttrTypeBase.td" +include "mlir/Dialect/Arith/IR/ArithBase.td" include "mlir/Dialect/XeGPU/IR/XeGPUAttrs.td" include "mlir/Dialect/XeGPU/IR/XeGPUDialect.td" include "mlir/Dialect/XeGPU/IR/XeGPUTypes.td" @@ -36,7 +36,7 @@ class XeGPU_Op traits = []>: static ::mlir::ParseResult parseProperties(::mlir::OpAsmParser &parser, ::mlir::OperationState &result) { - if (mlir::succeeded(parser.parseLess())) { + if (mlir::succeeded(parser.parseOptionalLess())) { if (parser.parseAttribute(result.propertiesAttr) || parser.parseGreater()) return failure(); } @@ -254,7 +254,7 @@ def XeGPU_LoadNdOp : XeGPU_Op<"load_nd", [AllElementTypesMatch<["value", "Tensor a block of data from memory to register. It takes a set of optional cache hints for each level of cache, L1, L2 and L3. If hardware does not have a correspoding cache, Corresponding cache hint attribute will be masked. - vnni transform is an hardware feature for Intel GPU, which is used to + VNNI transformation is an hardware feature for Intel GPU, which is used to do data packing during the load for B operand of matrix operation, if the bit width of the data type is less then 32 bits, e.g., fp16. And transpose is another Intel hardware feature, which will do transpose @@ -425,10 +425,6 @@ def XeGPU_CreateDescOp: XeGPU_Op<"create_tdesc", [Pure, ViewLikeOpInterface]> { %0 = memref.alloc() : memref<1024xf32> %1 = xegpu.create_tdesc %0[0, 4, 8, 12] {chunk_size = 8}: memref<1024xf32> -> TensorDesc<4x8xf32> ``` - - - - }]; let arguments = (ins XeGPU_BaseAddrType: $source, @@ -663,4 +659,153 @@ def XeGPU_UpdateOffsetOp: XeGPU_Op<"update_offset", }]; } +def XeGPU_DpasOp : XeGPU_Op<"dpas", [Pure, AllElementTypesMatch<["lhs", "rhs"]>]> { + let summary = "It performs mma computation"; + + let description = [{DPAS performs matrix multiplication on matrix A of `mxk` + size, B of `kxn` size, and accumulate on matrix C of `mxn` to the same size + matrix , `m=8`, `n=16` and `k=8 * 32/bit_width_of_elem_type`. So for fp16 + data type, the matrices are `A: vector<8x16xf16>`, `B: vector<16x16xf16>`, + and `C/D: vector<8x16xf32>`. Besides the matrix size requirements, DPAS + also requires A and B to be loaded with the required data layout. Specially, + VNNI layout is required for B operand. It is achieved via setting `vnni_axis = 0` + of the corresponding `load_nd` operator. To keep both operands as 3D vector, + operand A is loaded via setting `vnni_axis = 1` without impacting the + physical layouts change in register. Due to the VNNI transformation, A and B operands + are represented as 3D vector, with the last dimension representing the VNNI factor, + which is computed as `32/bit_width_of_elem_type`. Therefore, `A: vector<8x16xf16>` + is represented as `A: vector<8x8x2xf16>`, and `B: vector<16x16xf16>` is + represented as `B: vector<8x16x2xf16>`. + + Note: on PVC, the hardware can perform load with VNNI transformation when data + element type is 16-bit or lower precision, taking 2 or 4 elements from + the first dimension and inserted into the newly added innermost dimension. + }]; + + let arguments = (ins + XeGPU_DpasOpType : $lhs, + XeGPU_DpasOpType : $rhs, + Optional: $acc); + let results = (outs XeGPU_Vector2DType: $result); + + let extraClassDeclaration = [{ + VectorType getLhsType() { + return getLhs().getType(); + } + + VectorType getRhsType() { + return getRhs().getType(); + } + + VectorType getAccType() { + if (getAcc()) + return getAcc().getType(); + return {}; + } + + VectorType getResultType() { + return getResult().getType(); + } + }]; + + let assemblyFormat = [{ + $lhs `,` $rhs (`,` $acc^)? attr-dict `:` type($lhs)`,` type($rhs) (`,` type($acc)^)? `->` type($result) + }]; + + let hasVerifier = 1; +} + +def XeGPU_AtomicRMWOp: XeGPU_Op<"atomic_rmw", [Pure, + AllElementTypesMatch<["tensorDesc", "value", "result"]>, + AllShapesMatch<["tensorDesc", "mask", "value", "result"]>]> { + let summary = "Atomic ready-modify-write operation on the TensorDesc. "; + + let description = [{ + The `xegpu.atomic_rmw` operation provides a way to perform a read-modify-write + operation on the region described by the `TensorDesc` free from data races. The + `kind` enumeration specifies the modification to be performed, The `mask` operand + has the same shape with `TensorDesc`, and is used to enable or disable specific + data points of the `TensorDesc`. The `value` operand represents the new value to + be applied during the modification. + }]; + + let arguments = (ins + AtomicRMWKindAttr:$kind, + XeGPU_TensorDesc:$tensorDesc, + XeGPU_MaskType:$mask, + XeGPU_ValueType:$value); + + let results = (outs XeGPU_ValueType:$result); + + let assemblyFormat = [{ + $kind $tensorDesc `,` $mask `,` $value attr-dict `:` + type($tensorDesc) `,` type($mask) `,` type($value) `->` type($result) + }]; +} + +def XeGPU_AllocNbarrierOp: XeGPU_Op<"alloc_nbarrier", []> { + let summary = "It allocates a set of named barriers."; + let description = [{AllocNbarrier is to create a set of named barriers as + specified by `nbarrier_num`. Named barriers are workgroup level resources, + and are shared by all threads in the workgroup. For example, there are + up to 32 barriers (range 0-31) for each XeCore on PVC. A typical use case + is that a workgroup is partitioned into N subgroups of threads (N <= 32), + and each subgroup coordinating their work with a separate barrier with id + range from 0 to N respectively.}]; + let arguments = (ins I64Attr: $nbarrier_num); + let assemblyFormat = "$nbarrier_num attr-dict"; +} + +def XeGPU_InitNbarrierOp: XeGPU_Op<"init_nbarrier", []> { + let summary = "It assigns a named barrier to the current thread."; + let description = [{InitNbarrierOp assigns the named barrier with the specified + barrier ID (0~31) to the current thread. Multiple threads may bind to the + same named barrier, and the `participant_thread_num` specifies the total + number of threads associated with the nbarrier. It returns an object of + NbarrierType representing the barrier}]; + + let arguments = (ins I8: $nbarrier_id, + I8: $participant_thread_num); + let results = (outs XeGPU_Nbarrier: $result); + let assemblyFormat = [{ + $nbarrier_id `,` $participant_thread_num attr-dict `:` + type($nbarrier_id) `,` type($participant_thread_num) `->` qualified(type($result)) + }]; +} + +def XeGPU_NbarrierArriveOp: XeGPU_Op<"nbarrier_arrive", []> { + let summary = "It signals the arrival at the named barrier."; + let description = [{NbarrierArriveOp signals the hardware (or other threads) + that the current thread has produced its data for the consumer threads. When + the hardware signalled by `participant_thread_num` threads for the named barrier, + it will notify the threads waiting for the named barrier to continue their work.}]; + + let arguments = (ins XeGPU_Nbarrier: $nbarrier); + let assemblyFormat = [{ $nbarrier attr-dict `:` qualified(type($nbarrier))}]; +} + +def XeGPU_NbarrierWaitOp: XeGPU_Op<"nbarrier_wait", []> { + let summary = "It waits for a named barrier."; + let description = [{NbarrierWaitOp signals the hardware which named barrier + the current thread is waiting for, such that it can get notified when the + named barrier is completed.}]; + let arguments = (ins XeGPU_Nbarrier: $nbarrier); + let assemblyFormat = [{ $nbarrier attr-dict `:` qualified(type($nbarrier)) }]; +} + +def XeGPU_FenceOp: XeGPU_Op<"fence", []> { + let summary = "It synchronizes memory accesses."; + let description = [{It synchronizes the memory access between + write and following read or write. + 1. `Memory_kind` describes the memory kind. "global" means the global memory, + "slm" means the share local memory. + 2. `Fence_scope` describes the scope of fence. "Workgroup" means that the scope would be + within each workgroup. "GPU" means the scope would be across workgroups within the GPU. + }]; + let arguments = (ins XeGPU_MemoryScopeAttr: $memory_kind, + XeGPU_FenceScopeAttr: $fence_scope); + let assemblyFormat = [{`memory_kind` `=` `` $memory_kind `,` `fence_scope` `=` `` $fence_scope attr-dict}]; + let extraClassDeclaration = extraBaseClassDeclaration; +} + #endif // MLIR_DIALECT_XEGPU_IR_XEGPUOPS_TD diff --git a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUTypes.td b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUTypes.td index 4cd4e5411653..bab0e4afb1e5 100644 --- a/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUTypes.td +++ b/mlir/include/mlir/Dialect/XeGPU/IR/XeGPUTypes.td @@ -151,4 +151,15 @@ def XeGPU_TensorDesc: XeGPUTypeDef<"TensorDesc", "tensor_desc", } + +def XeGPU_Nbarrier: XeGPUTypeDef<"Nbarrier", "nbarrier", [], "mlir::Type"> { + let summary = "!xegpu.nbarrier a custom XeGPU type representing a barrier."; + + let extraClassDeclaration = [{ + static NbarrierType get(mlir::MLIRContext *context) { + return Base::get(context); + }; + }]; +} + #endif // MLIR_DIALECT_XEGPU_IR_XEGPUTYPES_TD diff --git a/mlir/lib/Dialect/XeGPU/IR/XeGPUOps.cpp b/mlir/lib/Dialect/XeGPU/IR/XeGPUOps.cpp index 23c5749c2309..22959224d56c 100644 --- a/mlir/lib/Dialect/XeGPU/IR/XeGPUOps.cpp +++ b/mlir/lib/Dialect/XeGPU/IR/XeGPUOps.cpp @@ -406,6 +406,28 @@ LogicalResult StoreScatterOp::verify() { return success(); } +//===----------------------------------------------------------------------===// +// XeGPU_DpasOp +//===----------------------------------------------------------------------===// +LogicalResult DpasOp::verify() { + int64_t lhsRank = getLhsType().getRank(); + int64_t rhsRank = getRhsType().getRank(); + + if (lhsRank != rhsRank || lhsRank != 3) + return emitOpError( + "lhs and rhs rank does not match for dpas op, or their rank is not 3."); + + if (getAcc() && getAccType() != getResultType()) + return emitOpError("Accumulator and Result for dpas op should have the " + "same type (both shape and element type)."); + + auto lhsShape = getLhsType().getShape(); + auto rhsShape = getRhsType().getShape(); + if (lhsShape[1] != rhsShape[0] || lhsShape[2] != rhsShape[2]) + return emitOpError("K-dimension or vnni-factor mismatch."); + + return success(); +} } // namespace xegpu } // namespace mlir diff --git a/mlir/test/Dialect/XeGPU/XeGPUOps.mlir b/mlir/test/Dialect/XeGPU/XeGPUOps.mlir index f0945c79a94a..00d32d2a2ee9 100644 --- a/mlir/test/Dialect/XeGPU/XeGPUOps.mlir +++ b/mlir/test/Dialect/XeGPU/XeGPUOps.mlir @@ -80,7 +80,7 @@ gpu.func @test_prefetch_vc(%src: ui64) { //CHECK: %[[R0:.*]] = xegpu.create_tdesc %arg0 [0, 8, 16, 24] {chunk_size = 2 : i64} : ui64 -> !xegpu.tensor_desc<4x2xf32, #xegpu.tdesc_attr> %1 = xegpu.create_tdesc %src[0, 8, 16, 24] {chunk_size = 2} : ui64 -> !xegpu.tensor_desc<4x2xf32, #xegpu.tdesc_attr> // CHECK: xegpu.prefetch %[[R0]] <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint}> : !xegpu.tensor_desc<4x2xf32, #xegpu.tdesc_attr> - xegpu.prefetch %1 <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint}>: !xegpu.tensor_desc<4x2xf32, #xegpu.tdesc_attr> + xegpu.prefetch %1 <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint}>: !xegpu.tensor_desc<4x2xf32, #xegpu.tdesc_attr> gpu.return } @@ -121,4 +121,59 @@ gpu.func @test_create_update_tdesc_vc(%src: ui64) { gpu.return } -} \ No newline at end of file +// CHECK: gpu.func @test_dpas_vc(%[[arg0:.*]]: vector<8x8x2xf16>, %[[arg1:.*]]: vector<8x16x2xf16>) +gpu.func @test_dpas_vc(%a : vector<8x8x2xf16>, %b: vector<8x16x2xf16>) { + // CHECK: %0 = xegpu.dpas %[[arg0]], %[[arg1]] : vector<8x8x2xf16>, vector<8x16x2xf16> -> vector<8x16xf32> + %1 = xegpu.dpas %a, %b: vector<8x8x2xf16>, vector<8x16x2xf16> -> vector<8x16xf32> + gpu.return +} + +// CHECK: gpu.func @test_atomic_rmw(%[[arg0:.*]]: ui64, %[[arg1:.*]]: vector<16xf32>, %[[arg2:.*]]: vector<16xi1>) +gpu.func @test_atomic_rmw(%src: ui64, %value : vector<16xf32>, %mask : vector<16xi1>) { + //CHECK: %[[R0:.*]] = xegpu.create_tdesc %[[arg0]] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] : ui64 -> !xegpu.tensor_desc<16xf32, #xegpu.tdesc_attr> + %1 = xegpu.create_tdesc %src[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: ui64 -> !xegpu.tensor_desc<16xf32, #xegpu.tdesc_attr> + //CHECK: %[[R1:.*]] = xegpu.atomic_rmw addf %[[R0]], %[[arg2]], %[[arg1]] : <16xf32, #xegpu.tdesc_attr>, vector<16xi1>, vector<16xf32> -> vector<16xf32> + xegpu.atomic_rmw addf %1, %mask, %value: !xegpu.tensor_desc<16xf32, #xegpu.tdesc_attr>, vector<16xi1>, vector<16xf32> -> vector<16xf32> + gpu.return +} + +// CHECK: gpu.func @alloc_nbarrier({{.*}}) { +gpu.func @alloc_nbarrier() { + // CHECK: xegpu.alloc_nbarrier + xegpu.alloc_nbarrier 8 + gpu.return +} + +// CHECK: gpu.func @init_nbarrier({{.*}}) { +gpu.func @init_nbarrier() { + //CHECK: %[[c1:.*]] = arith.constant 1 : i8 + //CHECK: %[[c16:.*]] = arith.constant 16 : i8 + %nbarrier_id = arith.constant 1 : i8 + %threads_count = arith.constant 16 : i8 + //CHECK: xegpu.init_nbarrier %[[c1]], %[[c16]] : i8, i8 -> !xegpu.nbarrier + %nbarrier = xegpu.init_nbarrier %nbarrier_id, %threads_count : i8, i8 -> !xegpu.nbarrier + gpu.return +} + +// CHECK: gpu.func @nbarrier_arrive(%[[arg0:.*]]: !xegpu.nbarrier) { +gpu.func @nbarrier_arrive(%nbarrier : !xegpu.nbarrier) { + //CHECK: xegpu.nbarrier_arrive %[[arg0]] : !xegpu.nbarrier + xegpu.nbarrier_arrive %nbarrier : !xegpu.nbarrier + gpu.return +} + +// CHECK: gpu.func @nbarrier_wait(%[[arg0:.*]]: !xegpu.nbarrier) { +gpu.func @nbarrier_wait(%nbarrier : !xegpu.nbarrier) { + //CHECK: xegpu.nbarrier_wait %[[arg0]] : !xegpu.nbarrier + xegpu.nbarrier_wait %nbarrier : !xegpu.nbarrier + gpu.return +} + +// CHECK-LABEL: gpu.func @fence({{.*}}) { +gpu.func @fence() { + //CHECK: xegpu.fence memory_kind = global, fence_scope = workgroup + xegpu.fence memory_kind = global, fence_scope = workgroup + gpu.return +} + +} diff --git a/mlir/test/Dialect/XeGPU/invalid.mlir b/mlir/test/Dialect/XeGPU/invalid.mlir index 5e29361ec690..7819ad60b97d 100644 --- a/mlir/test/Dialect/XeGPU/invalid.mlir +++ b/mlir/test/Dialect/XeGPU/invalid.mlir @@ -156,4 +156,32 @@ func.func @test_store_scatter_vc_2(%src: ui64) { xegpu.store %1, %2, %0 <{l1_hint = #xegpu.cache_hint}> : vector<4x2xf32>, !xegpu.tensor_desc<4x2xf32, #xegpu.tdesc_attr>, vector<4xi1> return +} + +// ----- +func.func @test_dpas_vc_1(%a : vector<8x4x2xf16>, %b: vector<8x16x2xf16>) { + // expected-error@+1 {{K-dimension or vnni-factor mismatch}} + %1 = xegpu.dpas %a, %b : vector<8x4x2xf16>, vector<8x16x2xf16> -> vector<8x16xf32> + return +} + +// ----- +func.func @test_dpas_vc_2(%a : vector<8x16xf16>, %b: vector<8x16x2xf16>) { + // expected-error@+1 {{lhs and rhs rank does not match for dpas op, or their rank is not 3}} + %1 = xegpu.dpas %a, %b : vector<8x16xf16>, vector<8x16x2xf16> -> vector<8x16xf32> + return +} + +// ----- +func.func @test_dpas_vc_3(%a : vector<8x16xf16>, %b: vector<16x16xf16>) { + // expected-error@+1 {{lhs and rhs rank does not match for dpas op, or their rank is not 3}} + %1 = xegpu.dpas %a, %b : vector<8x16xf16>, vector<16x16xf16> -> vector<8x16xf32> + return +} + +// ----- +func.func @test_dpas_vc_4(%a : vector<8x8x2xf16>, %b: vector<8x16x2xf16>, %c : vector<8x16xf16>) { + // expected-error@+1 {{Accumulator and Result for dpas op should have the same type}} + %1 = xegpu.dpas %a, %b, %c : vector<8x8x2xf16>, vector<8x16x2xf16>, vector<8x16xf16> -> vector<8x16xf32> + return } \ No newline at end of file -- GitLab From fc538b070de69315fe05105e8c0bc622fb61168a Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 24 Apr 2024 12:31:14 -0700 Subject: [PATCH 009/733] [SelectionDAG] Pass SDVTList instead of VTs to *SDNode constructors. NFC (#89880) All of these constructors were creating a SDVTList using an EVT* created by SDNode::getValueTypeList. This EVT needs to live at least as long as the SDNode that uses it. To do this, SDNode::getValueTypeList contains several function scoped static variables that hold the memory for the EVT. So the EVT lives until global destructors run. This is problematic since an EVT contains a Type* that points to memory allocated by an LLVMContext. If multiple LLVMContexts are used that don't have overlapping lifetimes, we can end up with stale or or incorrect pointers cached in the EVTs owned by SDNode::getValueTypeList. I want to try to make the EVTs be owned by SelectionDAG instead. This is already done for SDVTLists with more than 1 VT. The single value case is a very old optimizaton that should be re-evaluated. In order to do this, I need the SDVTLists to be created by SelectionDAG rather than by the SDNode itself. This patch doesn't change how the allocation is done yet. It just moves the code around. This patch does reduce the number of calls to getVTList since we now share with the call needed for the SDNode FoldingSet. Part of fixing #88233. --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 73 ++++++++-------- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 84 +++++++++++-------- 2 files changed, 86 insertions(+), 71 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 261f7e49e5c8..6dd16ef0e1e9 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1283,7 +1283,7 @@ private: unsigned DestAddrSpace; public: - AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, EVT VT, + AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, unsigned SrcAS, unsigned DestAS); unsigned getSrcAddressSpace() const { return SrcAddrSpace; } @@ -1573,8 +1573,9 @@ class ShuffleVectorSDNode : public SDNode { protected: friend class SelectionDAG; - ShuffleVectorSDNode(EVT VT, unsigned Order, const DebugLoc &dl, const int *M) - : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, getSDVTList(VT)), Mask(M) {} + ShuffleVectorSDNode(SDVTList VTs, unsigned Order, const DebugLoc &dl, + const int *M) + : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, VTs), Mask(M) {} public: ArrayRef getMask() const { @@ -1628,9 +1629,10 @@ class ConstantSDNode : public SDNode { const ConstantInt *Value; - ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val, EVT VT) + ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val, + SDVTList VTs) : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, 0, DebugLoc(), - getSDVTList(VT)), + VTs), Value(val) { ConstantSDNodeBits.IsOpaque = isOpaque; } @@ -1681,9 +1683,9 @@ class ConstantFPSDNode : public SDNode { const ConstantFP *Value; - ConstantFPSDNode(bool isTarget, const ConstantFP *val, EVT VT) + ConstantFPSDNode(bool isTarget, const ConstantFP *val, SDVTList VTs) : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, 0, - DebugLoc(), getSDVTList(VT)), + DebugLoc(), VTs), Value(val) {} public: @@ -1816,7 +1818,7 @@ class GlobalAddressSDNode : public SDNode { unsigned TargetFlags; GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, - const GlobalValue *GA, EVT VT, int64_t o, + const GlobalValue *GA, SDVTList VTs, int64_t o, unsigned TF); public: @@ -1839,10 +1841,10 @@ class FrameIndexSDNode : public SDNode { int FI; - FrameIndexSDNode(int fi, EVT VT, bool isTarg) - : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, - 0, DebugLoc(), getSDVTList(VT)), FI(fi) { - } + FrameIndexSDNode(int fi, SDVTList VTs, bool isTarg) + : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, 0, DebugLoc(), + VTs), + FI(fi) {} public: int getIndex() const { return FI; } @@ -1917,10 +1919,10 @@ class JumpTableSDNode : public SDNode { int JTI; unsigned TargetFlags; - JumpTableSDNode(int jti, EVT VT, bool isTarg, unsigned TF) - : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, - 0, DebugLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) { - } + JumpTableSDNode(int jti, SDVTList VTs, bool isTarg, unsigned TF) + : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, 0, DebugLoc(), + VTs), + JTI(jti), TargetFlags(TF) {} public: int getIndex() const { return JTI; } @@ -1943,19 +1945,19 @@ class ConstantPoolSDNode : public SDNode { Align Alignment; // Minimum alignment requirement of CP. unsigned TargetFlags; - ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o, + ConstantPoolSDNode(bool isTarget, const Constant *c, SDVTList VTs, int o, Align Alignment, unsigned TF) : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0, - DebugLoc(), getSDVTList(VT)), + DebugLoc(), VTs), Offset(o), Alignment(Alignment), TargetFlags(TF) { assert(Offset >= 0 && "Offset is too large"); Val.ConstVal = c; } - ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, EVT VT, int o, - Align Alignment, unsigned TF) + ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, SDVTList VTs, + int o, Align Alignment, unsigned TF) : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0, - DebugLoc(), getSDVTList(VT)), + DebugLoc(), VTs), Offset(o), Alignment(Alignment), TargetFlags(TF) { assert(Offset >= 0 && "Offset is too large"); Val.MachineCPVal = v; @@ -2003,9 +2005,9 @@ class TargetIndexSDNode : public SDNode { int64_t Offset; public: - TargetIndexSDNode(int Idx, EVT VT, int64_t Ofs, unsigned TF) - : SDNode(ISD::TargetIndex, 0, DebugLoc(), getSDVTList(VT)), - TargetFlags(TF), Index(Idx), Offset(Ofs) {} + TargetIndexSDNode(int Idx, SDVTList VTs, int64_t Ofs, unsigned TF) + : SDNode(ISD::TargetIndex, 0, DebugLoc(), VTs), TargetFlags(TF), + Index(Idx), Offset(Ofs) {} unsigned getTargetFlags() const { return TargetFlags; } int getIndex() const { return Index; } @@ -2215,8 +2217,8 @@ class RegisterSDNode : public SDNode { Register Reg; - RegisterSDNode(Register reg, EVT VT) - : SDNode(ISD::Register, 0, DebugLoc(), getSDVTList(VT)), Reg(reg) {} + RegisterSDNode(Register reg, SDVTList VTs) + : SDNode(ISD::Register, 0, DebugLoc(), VTs), Reg(reg) {} public: Register getReg() const { return Reg; } @@ -2251,10 +2253,10 @@ class BlockAddressSDNode : public SDNode { int64_t Offset; unsigned TargetFlags; - BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba, + BlockAddressSDNode(unsigned NodeTy, SDVTList VTs, const BlockAddress *ba, int64_t o, unsigned Flags) - : SDNode(NodeTy, 0, DebugLoc(), getSDVTList(VT)), - BA(ba), Offset(o), TargetFlags(Flags) {} + : SDNode(NodeTy, 0, DebugLoc(), VTs), BA(ba), Offset(o), + TargetFlags(Flags) {} public: const BlockAddress *getBlockAddress() const { return BA; } @@ -2292,9 +2294,10 @@ class ExternalSymbolSDNode : public SDNode { const char *Symbol; unsigned TargetFlags; - ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned TF, EVT VT) + ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned TF, + SDVTList VTs) : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, 0, - DebugLoc(), getSDVTList(VT)), + DebugLoc(), VTs), Symbol(Sym), TargetFlags(TF) {} public: @@ -2312,8 +2315,8 @@ class MCSymbolSDNode : public SDNode { MCSymbol *Symbol; - MCSymbolSDNode(MCSymbol *Symbol, EVT VT) - : SDNode(ISD::MCSymbol, 0, DebugLoc(), getSDVTList(VT)), Symbol(Symbol) {} + MCSymbolSDNode(MCSymbol *Symbol, SDVTList VTs) + : SDNode(ISD::MCSymbol, 0, DebugLoc(), VTs), Symbol(Symbol) {} public: MCSymbol *getMCSymbol() const { return Symbol; } @@ -3026,8 +3029,8 @@ class AssertAlignSDNode : public SDNode { Align Alignment; public: - AssertAlignSDNode(unsigned Order, const DebugLoc &DL, EVT VT, Align A) - : SDNode(ISD::AssertAlign, Order, DL, getSDVTList(VT)), Alignment(A) {} + AssertAlignSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, Align A) + : SDNode(ISD::AssertAlign, Order, DL, VTs), Alignment(A) {} Align getAlign() const { return Alignment; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 23ebfe466c74..6f7fbd510f24 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1701,8 +1701,9 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, const SDLoc &DL, assert(Elt->getBitWidth() == EltVT.getSizeInBits() && "APInt size does not match type size!"); unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant; + SDVTList VTs = getVTList(EltVT); FoldingSetNodeID ID; - AddNodeIDNode(ID, Opc, getVTList(EltVT), std::nullopt); + AddNodeIDNode(ID, Opc, VTs, std::nullopt); ID.AddPointer(Elt); ID.AddBoolean(isO); void *IP = nullptr; @@ -1712,7 +1713,7 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, const SDLoc &DL, return SDValue(N, 0); if (!N) { - N = newSDNode(isT, isO, Elt, EltVT); + N = newSDNode(isT, isO, Elt, VTs); CSEMap.InsertNode(N, IP); InsertNode(N); NewSDValueDbgMsg(SDValue(N, 0), "Creating constant: ", this); @@ -1762,8 +1763,9 @@ SDValue SelectionDAG::getConstantFP(const ConstantFP &V, const SDLoc &DL, // value, so that we don't have problems with 0.0 comparing equal to -0.0, and // we don't have issues with SNANs. unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP; + SDVTList VTs = getVTList(EltVT); FoldingSetNodeID ID; - AddNodeIDNode(ID, Opc, getVTList(EltVT), std::nullopt); + AddNodeIDNode(ID, Opc, VTs, std::nullopt); ID.AddPointer(&V); void *IP = nullptr; SDNode *N = nullptr; @@ -1772,7 +1774,7 @@ SDValue SelectionDAG::getConstantFP(const ConstantFP &V, const SDLoc &DL, return SDValue(N, 0); if (!N) { - N = newSDNode(isTarget, &V, EltVT); + N = newSDNode(isTarget, &V, VTs); CSEMap.InsertNode(N, IP); InsertNode(N); } @@ -1819,8 +1821,9 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, else Opc = isTargetGA ? ISD::TargetGlobalAddress : ISD::GlobalAddress; + SDVTList VTs = getVTList(VT); FoldingSetNodeID ID; - AddNodeIDNode(ID, Opc, getVTList(VT), std::nullopt); + AddNodeIDNode(ID, Opc, VTs, std::nullopt); ID.AddPointer(GV); ID.AddInteger(Offset); ID.AddInteger(TargetFlags); @@ -1829,7 +1832,7 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, return SDValue(E, 0); auto *N = newSDNode( - Opc, DL.getIROrder(), DL.getDebugLoc(), GV, VT, Offset, TargetFlags); + Opc, DL.getIROrder(), DL.getDebugLoc(), GV, VTs, Offset, TargetFlags); CSEMap.InsertNode(N, IP); InsertNode(N); return SDValue(N, 0); @@ -1837,14 +1840,15 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, SDValue SelectionDAG::getFrameIndex(int FI, EVT VT, bool isTarget) { unsigned Opc = isTarget ? ISD::TargetFrameIndex : ISD::FrameIndex; + SDVTList VTs = getVTList(VT); FoldingSetNodeID ID; - AddNodeIDNode(ID, Opc, getVTList(VT), std::nullopt); + AddNodeIDNode(ID, Opc, VTs, std::nullopt); ID.AddInteger(FI); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - auto *N = newSDNode(FI, VT, isTarget); + auto *N = newSDNode(FI, VTs, isTarget); CSEMap.InsertNode(N, IP); InsertNode(N); return SDValue(N, 0); @@ -1855,15 +1859,16 @@ SDValue SelectionDAG::getJumpTable(int JTI, EVT VT, bool isTarget, assert((TargetFlags == 0 || isTarget) && "Cannot set target flags on target-independent jump tables"); unsigned Opc = isTarget ? ISD::TargetJumpTable : ISD::JumpTable; + SDVTList VTs = getVTList(VT); FoldingSetNodeID ID; - AddNodeIDNode(ID, Opc, getVTList(VT), std::nullopt); + AddNodeIDNode(ID, Opc, VTs, std::nullopt); ID.AddInteger(JTI); ID.AddInteger(TargetFlags); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - auto *N = newSDNode(JTI, VT, isTarget, TargetFlags); + auto *N = newSDNode(JTI, VTs, isTarget, TargetFlags); CSEMap.InsertNode(N, IP); InsertNode(N); return SDValue(N, 0); @@ -1886,8 +1891,9 @@ SDValue SelectionDAG::getConstantPool(const Constant *C, EVT VT, ? getDataLayout().getABITypeAlign(C->getType()) : getDataLayout().getPrefTypeAlign(C->getType()); unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool; + SDVTList VTs = getVTList(VT); FoldingSetNodeID ID; - AddNodeIDNode(ID, Opc, getVTList(VT), std::nullopt); + AddNodeIDNode(ID, Opc, VTs, std::nullopt); ID.AddInteger(Alignment->value()); ID.AddInteger(Offset); ID.AddPointer(C); @@ -1896,7 +1902,7 @@ SDValue SelectionDAG::getConstantPool(const Constant *C, EVT VT, if (SDNode *E = FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - auto *N = newSDNode(isTarget, C, VT, Offset, *Alignment, + auto *N = newSDNode(isTarget, C, VTs, Offset, *Alignment, TargetFlags); CSEMap.InsertNode(N, IP); InsertNode(N); @@ -1913,8 +1919,9 @@ SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, EVT VT, if (!Alignment) Alignment = getDataLayout().getPrefTypeAlign(C->getType()); unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool; + SDVTList VTs = getVTList(VT); FoldingSetNodeID ID; - AddNodeIDNode(ID, Opc, getVTList(VT), std::nullopt); + AddNodeIDNode(ID, Opc, VTs, std::nullopt); ID.AddInteger(Alignment->value()); ID.AddInteger(Offset); C->addSelectionDAGCSEId(ID); @@ -1923,7 +1930,7 @@ SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, EVT VT, if (SDNode *E = FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - auto *N = newSDNode(isTarget, C, VT, Offset, *Alignment, + auto *N = newSDNode(isTarget, C, VTs, Offset, *Alignment, TargetFlags); CSEMap.InsertNode(N, IP); InsertNode(N); @@ -1961,7 +1968,7 @@ SDValue SelectionDAG::getValueType(EVT VT) { SDValue SelectionDAG::getExternalSymbol(const char *Sym, EVT VT) { SDNode *&N = ExternalSymbols[Sym]; if (N) return SDValue(N, 0); - N = newSDNode(false, Sym, 0, VT); + N = newSDNode(false, Sym, 0, getVTList(VT)); InsertNode(N); return SDValue(N, 0); } @@ -1970,7 +1977,7 @@ SDValue SelectionDAG::getMCSymbol(MCSymbol *Sym, EVT VT) { SDNode *&N = MCSymbols[Sym]; if (N) return SDValue(N, 0); - N = newSDNode(Sym, VT); + N = newSDNode(Sym, getVTList(VT)); InsertNode(N); return SDValue(N, 0); } @@ -1980,7 +1987,7 @@ SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, EVT VT, SDNode *&N = TargetExternalSymbols[std::pair(Sym, TargetFlags)]; if (N) return SDValue(N, 0); - N = newSDNode(true, Sym, TargetFlags, VT); + N = newSDNode(true, Sym, TargetFlags, getVTList(VT)); InsertNode(N); return SDValue(N, 0); } @@ -2196,9 +2203,10 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, } } + SDVTList VTs = getVTList(VT); FoldingSetNodeID ID; SDValue Ops[2] = { N1, N2 }; - AddNodeIDNode(ID, ISD::VECTOR_SHUFFLE, getVTList(VT), Ops); + AddNodeIDNode(ID, ISD::VECTOR_SHUFFLE, VTs, Ops); for (int i = 0; i != NElts; ++i) ID.AddInteger(MaskVec[i]); @@ -2212,7 +2220,7 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, int *MaskAlloc = OperandAllocator.Allocate(NElts); llvm::copy(MaskVec, MaskAlloc); - auto *N = newSDNode(VT, dl.getIROrder(), + auto *N = newSDNode(VTs, dl.getIROrder(), dl.getDebugLoc(), MaskAlloc); createOperands(N, Ops); @@ -2234,14 +2242,15 @@ SDValue SelectionDAG::getCommutedVectorShuffle(const ShuffleVectorSDNode &SV) { } SDValue SelectionDAG::getRegister(unsigned RegNo, EVT VT) { + SDVTList VTs = getVTList(VT); FoldingSetNodeID ID; - AddNodeIDNode(ID, ISD::Register, getVTList(VT), std::nullopt); + AddNodeIDNode(ID, ISD::Register, VTs, std::nullopt); ID.AddInteger(RegNo); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - auto *N = newSDNode(RegNo, VT); + auto *N = newSDNode(RegNo, VTs); N->SDNodeBits.IsDivergent = TLI->isSDNodeSourceOfDivergence(N, FLI, UA); CSEMap.InsertNode(N, IP); InsertNode(N); @@ -2290,9 +2299,10 @@ SDValue SelectionDAG::getBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset, bool isTarget, unsigned TargetFlags) { unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress; + SDVTList VTs = getVTList(VT); FoldingSetNodeID ID; - AddNodeIDNode(ID, Opc, getVTList(VT), std::nullopt); + AddNodeIDNode(ID, Opc, VTs, std::nullopt); ID.AddPointer(BA); ID.AddInteger(Offset); ID.AddInteger(TargetFlags); @@ -2300,7 +2310,7 @@ SDValue SelectionDAG::getBlockAddress(const BlockAddress *BA, EVT VT, if (SDNode *E = FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - auto *N = newSDNode(Opc, VT, BA, Offset, TargetFlags); + auto *N = newSDNode(Opc, VTs, BA, Offset, TargetFlags); CSEMap.InsertNode(N, IP); InsertNode(N); return SDValue(N, 0); @@ -2345,9 +2355,10 @@ SDValue SelectionDAG::getBitcast(EVT VT, SDValue V) { SDValue SelectionDAG::getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS) { + SDVTList VTs = getVTList(VT); SDValue Ops[] = {Ptr}; FoldingSetNodeID ID; - AddNodeIDNode(ID, ISD::ADDRSPACECAST, getVTList(VT), Ops); + AddNodeIDNode(ID, ISD::ADDRSPACECAST, VTs, Ops); ID.AddInteger(SrcAS); ID.AddInteger(DestAS); @@ -2356,7 +2367,7 @@ SDValue SelectionDAG::getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, return SDValue(E, 0); auto *N = newSDNode(dl.getIROrder(), dl.getDebugLoc(), - VT, SrcAS, DestAS); + VTs, SrcAS, DestAS); createOperands(N, Ops); CSEMap.InsertNode(N, IP); @@ -5713,14 +5724,14 @@ static SDValue foldCONCAT_VECTORS(const SDLoc &DL, EVT VT, /// Gets or creates the specified node. SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT) { + SDVTList VTs = getVTList(VT); FoldingSetNodeID ID; - AddNodeIDNode(ID, Opcode, getVTList(VT), std::nullopt); + AddNodeIDNode(ID, Opcode, VTs, std::nullopt); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return SDValue(E, 0); - auto *N = newSDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), - getVTList(VT)); + auto *N = newSDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs); CSEMap.InsertNode(N, IP); InsertNode(N); @@ -6667,16 +6678,17 @@ SDValue SelectionDAG::getAssertAlign(const SDLoc &DL, SDValue Val, Align A) { if (A == Align(1)) return Val; + SDVTList VTs = getVTList(Val.getValueType()); FoldingSetNodeID ID; - AddNodeIDNode(ID, ISD::AssertAlign, getVTList(Val.getValueType()), {Val}); + AddNodeIDNode(ID, ISD::AssertAlign, VTs, {Val}); ID.AddInteger(A.value()); void *IP = nullptr; if (SDNode *E = FindNodeOrInsertPos(ID, DL, IP)) return SDValue(E, 0); - auto *N = newSDNode(DL.getIROrder(), DL.getDebugLoc(), - Val.getValueType(), A); + auto *N = + newSDNode(DL.getIROrder(), DL.getDebugLoc(), VTs, A); createOperands(N, {Val}); CSEMap.InsertNode(N, IP); @@ -11797,17 +11809,17 @@ HandleSDNode::~HandleSDNode() { GlobalAddressSDNode::GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, - const GlobalValue *GA, EVT VT, + const GlobalValue *GA, SDVTList VTs, int64_t o, unsigned TF) - : SDNode(Opc, Order, DL, getSDVTList(VT)), Offset(o), TargetFlags(TF) { + : SDNode(Opc, Order, DL, VTs), Offset(o), TargetFlags(TF) { TheGlobal = GA; } AddrSpaceCastSDNode::AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, - EVT VT, unsigned SrcAS, + SDVTList VTs, unsigned SrcAS, unsigned DestAS) - : SDNode(ISD::ADDRSPACECAST, Order, dl, getSDVTList(VT)), - SrcAddrSpace(SrcAS), DestAddrSpace(DestAS) {} + : SDNode(ISD::ADDRSPACECAST, Order, dl, VTs), SrcAddrSpace(SrcAS), + DestAddrSpace(DestAS) {} MemSDNode::MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT memvt, MachineMemOperand *mmo) -- GitLab From 712d7dba4f27a1990241e02435d765a5a3808aea Mon Sep 17 00:00:00 2001 From: Bill Wendling <5993918+bwendling@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:39:33 -0700 Subject: [PATCH 010/733] [Clang] Improve testing for the flexible array member (#89462) Testing for the name of the flexible array member isn't as robust as testing the FieldDecl pointers. --- clang/lib/CodeGen/CGBuiltin.cpp | 23 ++++++++++++++--------- clang/lib/CodeGen/CodeGenFunction.h | 12 ++++++------ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 7e5f2edfc732..e67a600c1cdd 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -822,8 +822,9 @@ CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true); } -const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( - ASTContext &Ctx, const RecordDecl *RD, StringRef Name, uint64_t &Offset) { +const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberFieldAndOffset( + ASTContext &Ctx, const RecordDecl *RD, const FieldDecl *FAMDecl, + uint64_t &Offset) { const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel(); uint32_t FieldNo = 0; @@ -832,7 +833,7 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( return nullptr; for (const FieldDecl *FD : RD->fields()) { - if ((Name.empty() || FD->getNameAsString() == Name) && + if ((!FAMDecl || FD == FAMDecl) && Decl::isFlexibleArrayMemberLike( Ctx, FD, FD->getType(), StrictFlexArraysLevel, /*IgnoreTemplateOrMacroSubstitution=*/true)) { @@ -843,8 +844,8 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( QualType Ty = FD->getType(); if (Ty->isRecordType()) { - if (const FieldDecl *Field = FindFlexibleArrayMemberField( - Ctx, Ty->getAsRecordDecl(), Name, Offset)) { + if (const FieldDecl *Field = FindFlexibleArrayMemberFieldAndOffset( + Ctx, Ty->getAsRecordDecl(), FAMDecl, Offset)) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); Offset += Layout.getFieldOffset(FieldNo); return Field; @@ -930,12 +931,14 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, // Get the flexible array member Decl. const RecordDecl *OuterRD = nullptr; - std::string FAMName; + const FieldDecl *FAMDecl = nullptr; if (const auto *ME = dyn_cast(Base)) { // Check if \p Base is referencing the FAM itself. const ValueDecl *VD = ME->getMemberDecl(); OuterRD = VD->getDeclContext()->getOuterLexicalRecordContext(); - FAMName = VD->getNameAsString(); + FAMDecl = dyn_cast(VD); + if (!FAMDecl) + return nullptr; } else if (const auto *DRE = dyn_cast(Base)) { // Check if we're pointing to the whole struct. QualType Ty = DRE->getDecl()->getType(); @@ -974,9 +977,11 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, if (!OuterRD) return nullptr; + // We call FindFlexibleArrayMemberAndOffset even if FAMDecl is non-null to + // get its offset. uint64_t Offset = 0; - const FieldDecl *FAMDecl = - FindFlexibleArrayMemberField(Ctx, OuterRD, FAMName, Offset); + FAMDecl = + FindFlexibleArrayMemberFieldAndOffset(Ctx, OuterRD, FAMDecl, Offset); Offset = Ctx.toCharUnitsFromBits(Offset).getQuantity(); if (!FAMDecl || !FAMDecl->getType()->isCountAttributedType()) diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index ff1873325d40..a751649cdb59 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3204,12 +3204,12 @@ public: llvm::Value *Index, QualType IndexType, QualType IndexedType, bool Accessed); - // Find a struct's flexible array member. It may be embedded inside multiple - // sub-structs, but must still be the last field. - const FieldDecl *FindFlexibleArrayMemberField(ASTContext &Ctx, - const RecordDecl *RD, - StringRef Name, - uint64_t &Offset); + // Find a struct's flexible array member and get its offset. It may be + // embedded inside multiple sub-structs, but must still be the last field. + const FieldDecl * + FindFlexibleArrayMemberFieldAndOffset(ASTContext &Ctx, const RecordDecl *RD, + const FieldDecl *FAMDecl, + uint64_t &Offset); /// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns /// \p nullptr if either the attribute or the field doesn't exist. -- GitLab From f3f6f22dfcced21116710a477c78e0739c942139 Mon Sep 17 00:00:00 2001 From: Brian Gesiak Date: Wed, 24 Apr 2024 15:44:07 -0400 Subject: [PATCH 011/733] [mlir-lsp] Initialize Reply::method member (#89857) When debug level logging is enabled (by adding a call to `Logger::setLogLevel(Logger::Level::Debug)`), the `TransportInputTest.RequestWithInvalidParams` unit test logs: ``` [18:35:00.565] --> reply:(92) ``` The format string for this log statement is `"--> reply:{0}({1})"`, where `{0}` is the original request's method name (that is, the method name of the request being replied to), and `{1}` is the request ID. However, because the `Reply` class never initializes its `method` member, `{0}` is always empty. Initializing it results in the (nicer) log error below: ``` I[18:35:00.565] --> reply:invalid-params-request(92) ``` Because this is only ever logged for now, its not possible to add a test case for this. Future patches will rely on `method` being initialized, however, and will add test cases for this path. --- mlir/lib/Tools/lsp-server-support/Transport.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mlir/lib/Tools/lsp-server-support/Transport.cpp b/mlir/lib/Tools/lsp-server-support/Transport.cpp index 64dea35614c0..339c5f382516 100644 --- a/mlir/lib/Tools/lsp-server-support/Transport.cpp +++ b/mlir/lib/Tools/lsp-server-support/Transport.cpp @@ -51,12 +51,12 @@ private: Reply::Reply(const llvm::json::Value &id, llvm::StringRef method, JSONTransport &transport, std::mutex &transportOutputMutex) - : id(id), transport(&transport), + : method(method), id(id), transport(&transport), transportOutputMutex(transportOutputMutex) {} Reply::Reply(Reply &&other) - : replied(other.replied.load()), id(std::move(other.id)), - transport(other.transport), + : method(other.method), replied(other.replied.load()), + id(std::move(other.id)), transport(other.transport), transportOutputMutex(other.transportOutputMutex) { other.transport = nullptr; } -- GitLab From 63b6efeebf3003b075f384742ade189d2ed6b429 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Wed, 24 Apr 2024 19:51:00 +0000 Subject: [PATCH 012/733] [EntryExitInstrumenter] Don't invalidate analyses if no change was made --- llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp b/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp index f4207474e9a6..59a7dd1a00ed 100644 --- a/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp +++ b/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp @@ -137,7 +137,8 @@ static bool runOnFunction(Function &F, bool PostInlining) { PreservedAnalyses llvm::EntryExitInstrumenterPass::run(Function &F, FunctionAnalysisManager &AM) { - runOnFunction(F, PostInlining); + if (!runOnFunction(F, PostInlining)) + return PreservedAnalyses::all(); PreservedAnalyses PA; PA.preserveSet(); return PA; -- GitLab From 11bd19a7a25b291af61b6c06cb249b567c116d0e Mon Sep 17 00:00:00 2001 From: aniplcc Date: Thu, 25 Apr 2024 01:31:16 +0530 Subject: [PATCH 013/733] [libc][assert] define __STDC_VERSION_ASSERT_H__ (#87592) Fixes #87561 --- libc/include/assert.h.def | 1 + libc/include/llvm-libc-macros/CMakeLists.txt | 6 ++++++ libc/include/llvm-libc-macros/assert-macros.h | 14 ++++++++++++++ libc/test/include/CMakeLists.txt | 10 ++++++++++ libc/test/include/assert_test.cpp | 15 +++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 libc/include/llvm-libc-macros/assert-macros.h create mode 100644 libc/test/include/assert_test.cpp diff --git a/libc/include/assert.h.def b/libc/include/assert.h.def index e006133a7654..15077e53e2ca 100644 --- a/libc/include/assert.h.def +++ b/libc/include/assert.h.def @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "__llvm-libc-common.h" +#include "llvm-libc-macros/assert-macros.h" // This file may be usefully included multiple times to change assert()'s // definition based on NDEBUG. diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt index 382cb8ee417e..68ba110aec80 100644 --- a/libc/include/llvm-libc-macros/CMakeLists.txt +++ b/libc/include/llvm-libc-macros/CMakeLists.txt @@ -31,6 +31,12 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) endif() +add_macro_header( + assert_macros + HDR + assert-macros.h +) + add_macro_header( generic_error_number_macros HDR diff --git a/libc/include/llvm-libc-macros/assert-macros.h b/libc/include/llvm-libc-macros/assert-macros.h new file mode 100644 index 000000000000..44e14543d856 --- /dev/null +++ b/libc/include/llvm-libc-macros/assert-macros.h @@ -0,0 +1,14 @@ +//===-- Definition of macros to be used with assert functions -------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef __LLVM_LIBC_MACROS_ASSERT_MACROS_H +#define __LLVM_LIBC_MACROS_ASSERT_MACROS_H + +#define __STDC_VERSION_ASSERT_H__ 202311L + +#endif // __LLVM_LIBC_MACROS_ASSERT_MACROS_H diff --git a/libc/test/include/CMakeLists.txt b/libc/test/include/CMakeLists.txt index 8d8dff53169f..03c31855e352 100644 --- a/libc/test/include/CMakeLists.txt +++ b/libc/test/include/CMakeLists.txt @@ -1,5 +1,15 @@ add_custom_target(libc_include_tests) +add_libc_test( + assert_test + SUITE + libc_include_tests + SRCS + assert_test.cpp + DEPENDS + libc.include.llvm-libc-macros.assert_macros +) + add_libc_test( sys_queue_test SUITE diff --git a/libc/test/include/assert_test.cpp b/libc/test/include/assert_test.cpp new file mode 100644 index 000000000000..78709bbcdd59 --- /dev/null +++ b/libc/test/include/assert_test.cpp @@ -0,0 +1,15 @@ +//===-- Unittests for assert ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "include/llvm-libc-macros/assert-macros.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcAssertTest, VersionMacro) { + // 7.2p3 an integer constant expression with a value equivalent to 202311L. + EXPECT_EQ(__STDC_VERSION_ASSERT_H__, 202311L); +} -- GitLab From c5dcb5239e5a3ee68155ba2d09d1fa37ca512cd7 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 24 Apr 2024 12:57:26 -0700 Subject: [PATCH 014/733] [SelectionDAG] Move GlobalAddressSDNode and AddrSpaceCastSDNode constructors into header. NFC These constructors are no more complicated than any of the other *SDNode constructors that are already in the header. --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 8 ++++++-- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 14 -------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 6dd16ef0e1e9..70d6b09a0c89 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1284,7 +1284,9 @@ private: public: AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, - unsigned SrcAS, unsigned DestAS); + unsigned SrcAS, unsigned DestAS) + : SDNode(ISD::ADDRSPACECAST, Order, dl, VTs), SrcAddrSpace(SrcAS), + DestAddrSpace(DestAS) {} unsigned getSrcAddressSpace() const { return SrcAddrSpace; } unsigned getDestAddressSpace() const { return DestAddrSpace; } @@ -1819,7 +1821,9 @@ class GlobalAddressSDNode : public SDNode { GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, const GlobalValue *GA, SDVTList VTs, int64_t o, - unsigned TF); + unsigned TF) + : SDNode(Opc, Order, DL, VTs), TheGlobal(GA), Offset(o), TargetFlags(TF) { + } public: const GlobalValue *getGlobal() const { return TheGlobal; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 6f7fbd510f24..5b7d6376d7d7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -11807,20 +11807,6 @@ HandleSDNode::~HandleSDNode() { DropOperands(); } -GlobalAddressSDNode::GlobalAddressSDNode(unsigned Opc, unsigned Order, - const DebugLoc &DL, - const GlobalValue *GA, SDVTList VTs, - int64_t o, unsigned TF) - : SDNode(Opc, Order, DL, VTs), Offset(o), TargetFlags(TF) { - TheGlobal = GA; -} - -AddrSpaceCastSDNode::AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, - SDVTList VTs, unsigned SrcAS, - unsigned DestAS) - : SDNode(ISD::ADDRSPACECAST, Order, dl, VTs), SrcAddrSpace(SrcAS), - DestAddrSpace(DestAS) {} - MemSDNode::MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT memvt, MachineMemOperand *mmo) : SDNode(Opc, Order, dl, VTs), MemoryVT(memvt), MMO(mmo) { -- GitLab From 13188bcd9f748dee13cf848340833f6eec2d90d4 Mon Sep 17 00:00:00 2001 From: AtariDreams Date: Wed, 24 Apr 2024 16:14:02 -0400 Subject: [PATCH 015/733] [GlobalISel]: Simplify udiv lowering by determining known zeros (#89678) --- .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 9 ++++++- .../AArch64/GlobalISel/combine-udiv.ll | 26 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 050f42e9039b..653e7689b577 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -5069,6 +5069,9 @@ MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) { const unsigned EltBits = ScalarTy.getScalarSizeInBits(); LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(Ty); LLT ScalarShiftAmtTy = ShiftAmtTy.getScalarType(); + + unsigned KnownLeadingZeros = + KB ? KB->getKnownBits(LHS).countMinLeadingZeros() : 0; auto &MIB = Builder; bool UseNPQ = false; @@ -5086,8 +5089,12 @@ MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) { // at the end. // TODO: Use undef values for divisor of 1. if (!Divisor.isOne()) { + + // UnsignedDivisionByConstantInfo doesn't work correctly if leading zeros + // in the dividend exceeds the leading zeros for the divisor. UnsignedDivisionByConstantInfo magics = - UnsignedDivisionByConstantInfo::get(Divisor); + UnsignedDivisionByConstantInfo::get( + Divisor, std::min(KnownLeadingZeros, Divisor.countl_zero())); Magic = std::move(magics.Magic); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-udiv.ll b/llvm/test/CodeGen/AArch64/GlobalISel/combine-udiv.ll index 9a525151ca32..c97a00ccdd45 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-udiv.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-udiv.ll @@ -243,3 +243,29 @@ define <8 x i16> @pr38477(<8 x i16> %a0) { %1 = udiv <8 x i16> %a0, ret <8 x i16> %1 } + +define i32 @udiv_div_by_180(i32 %x) +; SDAG-LABEL: udiv_div_by_180: +; SDAG: // %bb.0: +; SDAG-NEXT: mov w8, #5826 // =0x16c2 +; SDAG-NEXT: and w9, w0, #0xff +; SDAG-NEXT: movk w8, #364, lsl #16 +; SDAG-NEXT: umull x8, w9, w8 +; SDAG-NEXT: lsr x0, x8, #32 +; SDAG-NEXT: // kill: def $w0 killed $w0 killed $x0 +; SDAG-NEXT: ret +; +; GISEL-LABEL: udiv_div_by_180: +; GISEL: // %bb.0: +; GISEL-NEXT: uxtb w8, w0 +; GISEL-NEXT: mov w9, #5826 // =0x16c2 +; GISEL-NEXT: movk w9, #364, lsl #16 +; GISEL-NEXT: umull x8, w8, w9 +; GISEL-NEXT: lsr x0, x8, #32 +; GISEL-NEXT: // kill: def $w0 killed $w0 killed $x0 +; GISEL-NEXT: ret +{ + %truncate = and i32 %x, 255 + %udiv = udiv i32 %truncate, 180 + ret i32 %udiv +} -- GitLab From 96c45a7fa12619c3abd6b81effe4c80f0916b78b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 24 Apr 2024 13:16:02 -0700 Subject: [PATCH 016/733] [MC] Rename temporary symbols of empty name to ".L0 " (#89693) Temporary symbols generated for .eh_frame and .debug_line have an empty name, which appear in .symtab in the presence of RISC-V style linker relaxation and will not be discarded by ld/objcopy --discard-locals (-X). In contrast, GNU assembler's riscv port assigns a fake name ".L0 " (with a trailing space) to these symbols so that will be discarded by ld/objcopy --discard-locals. This patch matches the GNU behavior. Since Clang's RISC-V targets pass -X to ld, and GNU ld defaults to -X for RISC-V targets, these ".L0 " symbols will be discarded after linking by default, as expected by users. The llvm-symbolizer special case for RISC-V `SF_FormatSpecific` symbols https://reviews.llvm.org/D98669 needs to be adjusted. Note: `"":` in assembly currently crashes. --- lld/test/ELF/mips-eh_frame-pic.s | 4 +-- llvm/include/llvm/Object/ELFObjectFile.h | 5 ++- llvm/lib/MC/ELFObjectWriter.cpp | 6 ++++ llvm/test/CodeGen/RISCV/fixups-diff.ll | 2 +- .../LoongArch/dwarf-loongarch-relocs.ll | 18 +++++------ .../DebugInfo/RISCV/dwarf-riscv-relocs.ll | 12 +++---- .../test/DebugInfo/RISCV/relax-debug-frame.ll | 10 +++--- ...name-symbol.s => riscv-temporary-symbol.s} | 5 +-- .../JITLink/RISCV/anonymous_symbol.s | 2 +- llvm/test/MC/ELF/RISCV/gen-dwarf.s | 26 +++++++-------- llvm/test/MC/RISCV/cfi-advance.s | 32 +++++++++++++++---- llvm/test/MC/RISCV/fde-reloc.s | 2 +- llvm/test/MC/RISCV/scoped-relaxation.s | 6 ++-- 13 files changed, 78 insertions(+), 52 deletions(-) rename llvm/test/DebugInfo/Symbolize/ELF/{riscv-empty-name-symbol.s => riscv-temporary-symbol.s} (71%) diff --git a/lld/test/ELF/mips-eh_frame-pic.s b/lld/test/ELF/mips-eh_frame-pic.s index a84c36b0e5ec..c04dbdf57b08 100644 --- a/lld/test/ELF/mips-eh_frame-pic.s +++ b/lld/test/ELF/mips-eh_frame-pic.s @@ -36,8 +36,8 @@ # RELOCS: .rel{{a?}}.eh_frame { # ABS32-RELOCS-NEXT: 0x1C R_MIPS_32 .text # ABS64-RELOCS-NEXT: 0x1C R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE .text -# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE -# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 +# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE .L0 +# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 .L0 # RELOCS-NEXT: } # ABS64-EH-FRAME: Augmentation data: 0C diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 1d457be93741..4494d9b96189 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -801,9 +801,8 @@ Expected ELFObjectFile::getSymbolFlags(DataRefImpl Sym) const { } else if (EF.getHeader().e_machine == ELF::EM_RISCV) { if (Expected NameOrErr = getSymbolName(Sym)) { StringRef Name = *NameOrErr; - // Mark empty name symbols (used for label differences) and mapping - // symbols. - if (Name.empty() || Name.starts_with("$d") || Name.starts_with("$x")) + // Mark fake labels (used for label differences) and mapping symbols. + if (Name == ".L0 " || Name.starts_with("$d") || Name.starts_with("$x")) Result |= SymbolRef::SF_FormatSpecific; } else { // TODO: Actually report errors helpfully. diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 005521bad6e0..b8ef2654ed6e 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -725,7 +725,13 @@ void ELFWriter::computeSymbolTable( HasLargeSectionIndex = true; } + // Temporary symbols generated for certain assembler features (.eh_frame, + // .debug_line) of an empty name may be referenced by relocations due to + // linker relaxation. Rename them to ".L0 " to match the gas fake label name + // and allow ld/objcopy --discard-locals to discard such symbols. StringRef Name = Symbol.getName(); + if (Name.empty()) + Name = ".L0 "; // Sections have their own string table if (Symbol.getType() != ELF::STT_SECTION) { diff --git a/llvm/test/CodeGen/RISCV/fixups-diff.ll b/llvm/test/CodeGen/RISCV/fixups-diff.ll index cc1c87b1fe37..84a7d18ed150 100644 --- a/llvm/test/CodeGen/RISCV/fixups-diff.ll +++ b/llvm/test/CodeGen/RISCV/fixups-diff.ll @@ -27,7 +27,7 @@ entry: ; CHECK: } ; CHECK: Section {{.*}} .rela.eh_frame { -; CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 +; CHECK-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 ; CHECK-NEXT: } !llvm.dbg.cu = !{!0} diff --git a/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll b/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll index d6a1d8d6e136..d28836d56037 100644 --- a/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll +++ b/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll @@ -18,21 +18,21 @@ ; RELOCS-BOTH: Section ({{.*}}) .rela.debug_frame { ; RELOCS-NORL-NEXT: 0x1C R_LARCH_32 .debug_frame 0x0 ; RELOCS-NORL-NEXT: 0x20 R_LARCH_64 .text 0x0 -; RELOCS-ENRL-NEXT: 0x1C R_LARCH_32 0x0 -; RELOCS-ENRL-NEXT: 0x20 R_LARCH_64 0x0 -; RELOCS-ENRL-NEXT: 0x28 R_LARCH_ADD64 0x0 -; RELOCS-ENRL-NEXT: 0x28 R_LARCH_SUB64 0x0 -; RELOCS-ENRL-NEXT: 0x3F R_LARCH_ADD6 0x0 -; RELOCS-ENRL-NEXT: 0x3F R_LARCH_SUB6 0x0 +; RELOCS-ENRL-NEXT: 0x1C R_LARCH_32 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x20 R_LARCH_64 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x28 R_LARCH_ADD64 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x28 R_LARCH_SUB64 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x3F R_LARCH_ADD6 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x3F R_LARCH_SUB6 .L0 0x0 ; RELOCS-BOTH-NEXT: } ; RELOCS-BOTH: Section ({{.*}}) .rela.debug_line { ; RELOCS-BOTH-NEXT: 0x22 R_LARCH_32 .debug_line_str 0x0 ; RELOCS-BOTH-NEXT: 0x31 R_LARCH_32 .debug_line_str 0x2 ; RELOCS-BOTH-NEXT: 0x46 R_LARCH_32 .debug_line_str 0x1B ; RELOCS-NORL-NEXT: 0x4F R_LARCH_64 .text 0x0 -; RELOCS-ENRL-NEXT: 0x4F R_LARCH_64 0x0 -; RELOCS-ENRL-NEXT: 0x5F R_LARCH_ADD16 0x0 -; RELOCS-ENRL-NEXT: 0x5F R_LARCH_SUB16 0x0 +; RELOCS-ENRL-NEXT: 0x4F R_LARCH_64 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x5F R_LARCH_ADD16 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x5F R_LARCH_SUB16 .L0 0x0 ; RELOCS-BOTH-NEXT: } ; RELOCS-BOTH-NEXT: ] diff --git a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll index e5de1713f4e0..99594b5e01e9 100644 --- a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll +++ b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll @@ -6,14 +6,14 @@ ; Check that we actually have relocations, otherwise this is kind of pointless. ; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_info { -; READOBJ-RELOCS: 0x1B R_RISCV_ADD32 0x0 -; READOBJ-RELOCS-NEXT: 0x1B R_RISCV_SUB32 0x0 +; READOBJ-RELOCS: 0x1B R_RISCV_ADD32 .L0 0x0 +; READOBJ-RELOCS-NEXT: 0x1B R_RISCV_SUB32 .L0 0x0 ; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_frame { -; READOBJ-RELOCS: 0x20 R_RISCV_ADD32 0x0 -; READOBJ-RELOCS-NEXT: 0x20 R_RISCV_SUB32 0x0 +; READOBJ-RELOCS: 0x20 R_RISCV_ADD32 .L0 0x0 +; READOBJ-RELOCS-NEXT: 0x20 R_RISCV_SUB32 .L0 0x0 ; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_line { -; READOBJ-RELOCS: 0x5A R_RISCV_ADD16 0x0 -; READOBJ-RELOCS-NEXT: 0x5A R_RISCV_SUB16 0x0 +; READOBJ-RELOCS: 0x5A R_RISCV_ADD16 .L0 0x0 +; READOBJ-RELOCS-NEXT: 0x5A R_RISCV_SUB16 .L0 0x0 ; Check that we can print the source, even with relocations. ; OBJDUMP-SOURCE: Disassembly of section .text: diff --git a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll index f655a7c0a7ef..ffef0ec23406 100644 --- a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll +++ b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll @@ -4,11 +4,11 @@ ; RUN: | FileCheck -check-prefix=RELAX-DWARFDUMP %s ; ; RELAX: Section ({{.*}}) .rela.eh_frame { -; RELAX-NEXT: 0x1C R_RISCV_32_PCREL 0x0 -; RELAX-NEXT: 0x30 R_RISCV_32_PCREL 0x0 -; RELAX-NEXT: 0x44 R_RISCV_32_PCREL 0x0 -; RELAX-NEXT: 0x48 R_RISCV_ADD32 0x0 -; RELAX-NEXT: 0x48 R_RISCV_SUB32 0x0 +; RELAX-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 +; RELAX-NEXT: 0x30 R_RISCV_32_PCREL .L0 0x0 +; RELAX-NEXT: 0x44 R_RISCV_32_PCREL .L0 0x0 +; RELAX-NEXT: 0x48 R_RISCV_ADD32 .L0 0x0 +; RELAX-NEXT: 0x48 R_RISCV_SUB32 .L0 0x0 ; RELAX-NEXT: } ; RELAX-DWARFDUMP-NOT: error: failed to compute relocation diff --git a/llvm/test/DebugInfo/Symbolize/ELF/riscv-empty-name-symbol.s b/llvm/test/DebugInfo/Symbolize/ELF/riscv-temporary-symbol.s similarity index 71% rename from llvm/test/DebugInfo/Symbolize/ELF/riscv-empty-name-symbol.s rename to llvm/test/DebugInfo/Symbolize/ELF/riscv-temporary-symbol.s index 1e0fa8a30618..0b54f104ab95 100644 --- a/llvm/test/DebugInfo/Symbolize/ELF/riscv-empty-name-symbol.s +++ b/llvm/test/DebugInfo/Symbolize/ELF/riscv-temporary-symbol.s @@ -1,10 +1,11 @@ # REQUIRES: riscv-registered-target -## Ignore empty name symbols. +## Ignore .L0 symbols that are generated by LLVM integrated assembler and GNU +## assembler for .debug_line/.eh_frame related assembler directives. # RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t # RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYM -# SYM: 0000000000000004 0 NOTYPE LOCAL DEFAULT [[#]] {{$}} +# SYM: 0000000000000004 0 NOTYPE LOCAL DEFAULT [[#]] .L0 {{$}} # SYM: 0000000000000000 0 NOTYPE GLOBAL DEFAULT [[#]] foo ## Make sure we test at an address larger than or equal to an empty name symbol. diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s b/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s index a5038022dfe0..e7114e4d643c 100644 --- a/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s @@ -7,7 +7,7 @@ # the section start and section end. So that by relocating these symbol, the section length # can be calculated. # -# CHECK: Creating defined graph symbol for ELF symbol "" +# CHECK: Creating defined graph symbol for ELF symbol ".L0 " # CHECK: Creating defined graph symbol for ELF symbol "main" .text .globl main diff --git a/llvm/test/MC/ELF/RISCV/gen-dwarf.s b/llvm/test/MC/ELF/RISCV/gen-dwarf.s index 342ed1cc0e7e..34d02f5da44f 100644 --- a/llvm/test/MC/ELF/RISCV/gen-dwarf.s +++ b/llvm/test/MC/ELF/RISCV/gen-dwarf.s @@ -40,28 +40,28 @@ # CHECK-NEXT: 0x00000020: [DW_RLE_end_of_list ] # RELOC: Section ([[#]]) .rela.eh_frame { -# RELOC-NEXT: 0x1C R_RISCV_32_PCREL 0x0 -# RELOC-NEXT: 0x20 R_RISCV_ADD32 0x0 -# RELOC-NEXT: 0x20 R_RISCV_SUB32 0x0 -# RELOC-NEXT: 0x25 R_RISCV_SET6 0x0 -# RELOC-NEXT: 0x25 R_RISCV_SUB6 0x0 -# RELOC-NEXT: 0x34 R_RISCV_32_PCREL 0x0 +# RELOC-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 +# RELOC-NEXT: 0x20 R_RISCV_ADD32 .L0 0x0 +# RELOC-NEXT: 0x20 R_RISCV_SUB32 .L0 0x0 +# RELOC-NEXT: 0x25 R_RISCV_SET6 .L0 0x0 +# RELOC-NEXT: 0x25 R_RISCV_SUB6 .L0 0x0 +# RELOC-NEXT: 0x34 R_RISCV_32_PCREL .L0 0x0 # RELOC-NEXT: } # RELOC: Section ([[#]]) .rela.debug_rnglists { # RELOC-NEXT: 0xD R_RISCV_64 .text.foo 0x0 -# RELOC-NEXT: 0x15 R_RISCV_SET_ULEB128 0x0 +# RELOC-NEXT: 0x15 R_RISCV_SET_ULEB128 .L0 0x0 # RELOC-NEXT: 0x15 R_RISCV_SUB_ULEB128 .text.foo 0x0 # RELOC-NEXT: 0x17 R_RISCV_64 .text.bar 0x0 # RELOC-NEXT: } # RELOC: Section ([[#]]) .rela.debug_line { -# RELOC: R_RISCV_ADD16 0x0 -# RELOC-NEXT: R_RISCV_SUB16 0x0 -# RELOC-NEXT: R_RISCV_ADD16 0x0 -# RELOC-NEXT: R_RISCV_SUB16 0x0 -# RELOC-NEXT: R_RISCV_ADD16 0x0 -# RELOC-NEXT: R_RISCV_SUB16 0x0 +# RELOC: R_RISCV_ADD16 .L0 0x0 +# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0 +# RELOC-NEXT: R_RISCV_ADD16 .L0 0x0 +# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0 +# RELOC-NEXT: R_RISCV_ADD16 .L0 0x0 +# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0 # RELOC: } # RELOC: Hex dump of section '.eh_frame': diff --git a/llvm/test/MC/RISCV/cfi-advance.s b/llvm/test/MC/RISCV/cfi-advance.s index c4af390be757..b99af38f553a 100644 --- a/llvm/test/MC/RISCV/cfi-advance.s +++ b/llvm/test/MC/RISCV/cfi-advance.s @@ -1,13 +1,27 @@ # RUN: llvm-mc -filetype=obj -triple riscv32 %s -o %t.o -# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=CHECK %s +# RUN: llvm-readelf -sr %t.o | FileCheck %s # RUN: llvm-dwarfdump --debug-frame %t.o 2>&1 \ # RUN: | FileCheck -check-prefix=CHECK-DWARFDUMP %s -# CHECK: .rela.eh_frame { -# CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 -# CHECK-NEXT: 0x35 R_RISCV_SET6 0x0 -# CHECK-NEXT: 0x35 R_RISCV_SUB6 0x0 -# CHECK-NEXT: } + +# CHECK: Relocation section '.rela.text1' at offset {{.*}} contains 1 entries: +# CHECK-NEXT: Offset Info Type Sym. Value Symbol's Name + Addend +# CHECK-NEXT: 00000000 00000313 R_RISCV_CALL_PLT 00000004 .L0 + 0 +# CHECK-EMPTY: +# CHECK-NEXT: Relocation section '.rela.eh_frame' at offset {{.*}} contains 3 entries: +# CHECK: Offset Info Type Sym. Value Symbol's Name + Addend +# CHECK-NEXT: 0000001c 00000139 R_RISCV_32_PCREL 00000000 .L0 + 0 +# CHECK-NEXT: 00000035 00000b35 R_RISCV_SET6 00010178 .L0 + 0 +# CHECK-NEXT: 00000035 00000934 R_RISCV_SUB6 0001016e .L0 + 0 +# CHECK-EMPTY: +# CHECK: Symbol table '.symtab' contains 15 entries: +# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name +# CHECK-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND +# CHECK-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}} +# CHECK: 3: 00000004 0 NOTYPE LOCAL DEFAULT 2 .L0{{$}} +# CHECK: 9: 0001016e 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}} +# CHECK: 11: 00010178 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}} + # CHECK-DWARFDUMP: DW_CFA_advance_loc1: 104 # CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8 # CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc2: 259 @@ -23,6 +37,9 @@ test: .cfi_startproc nop +## This looks similar to fake label names ".L0 ". Even if this is ".L0 ", +## the assembler will not conflate it with fake labels. +.L0: .zero 100, 0x90 .cfi_def_cfa_offset 8 nop @@ -36,3 +53,6 @@ test: .cfi_def_cfa_offset 8 nop .cfi_endproc + +.section .text1,"ax" +call .L0 diff --git a/llvm/test/MC/RISCV/fde-reloc.s b/llvm/test/MC/RISCV/fde-reloc.s index 1db8929e0747..81ec426c8b61 100644 --- a/llvm/test/MC/RISCV/fde-reloc.s +++ b/llvm/test/MC/RISCV/fde-reloc.s @@ -12,7 +12,7 @@ func: .cfi_endproc # CHECK: Section (4) .rela.eh_frame { -# CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 +# CHECK-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 # CHECK-NEXT: } # CHECK: Hex dump of section '.eh_frame': # CHECK-NEXT: 0x00000000 10000000 00000000 017a5200 017c0101 diff --git a/llvm/test/MC/RISCV/scoped-relaxation.s b/llvm/test/MC/RISCV/scoped-relaxation.s index 0b797ee5aca5..56394fd80532 100644 --- a/llvm/test/MC/RISCV/scoped-relaxation.s +++ b/llvm/test/MC/RISCV/scoped-relaxation.s @@ -9,7 +9,7 @@ .dword function - . # CHECK: 0x0 R_RISCV_ADD64 function 0x0 -# CHECK-NEXT: 0x0 R_RISCV_SUB64 0x0 +# CHECK-NEXT: 0x0 R_RISCV_SUB64 .L0 0x0 # Relaxed reference, this will resolve to a pair of `RISCV_ADD64` and # `RISCV_SUB64` relocation. @@ -19,7 +19,7 @@ .option pop # CHECK: 0x8 R_RISCV_ADD64 function 0x0 -# CHECK-NEXT: 0x8 R_RISCV_SUB64 0x0 +# CHECK-NEXT: 0x8 R_RISCV_SUB64 .L0 0x0 # Unrelaxed reference, this will resolve to a pair of `RISCV_ADD64` and # `RISCV_SUB64` relocation due to relaxation being sticky to the file. @@ -29,6 +29,6 @@ .option pop # CHECK: 0x10 R_RISCV_ADD64 function 0x0 -# CHECK-NEXT: 0x10 R_RISCV_SUB64 0x0 +# CHECK-NEXT: 0x10 R_RISCV_SUB64 .L0 0x0 # CHECK: } -- GitLab From 7b06ec073d0bd8abad1274d12900a849bd3829c5 Mon Sep 17 00:00:00 2001 From: Mircea Trofin Date: Wed, 24 Apr 2024 13:31:55 -0700 Subject: [PATCH 017/733] [compiler-rt] Make sure `memprof` and `ctx_profile` unittests run (#89814) They weren't run before as part of `check-compiler-rt`. Verified by adding a `EXPECT_TRUE(false)` in both and observing test failure. --- compiler-rt/test/CMakeLists.txt | 3 ++ compiler-rt/test/ctx_profile/CMakeLists.txt | 21 +++++++++++++ .../test/ctx_profile/Unit/lit.site.cfg.py.in | 27 +++++++++++++++++ compiler-rt/test/memprof/CMakeLists.txt | 13 ++++++++ .../test/memprof/Unit/lit.site.cfg.py.in | 30 +++++++++++++++++++ 5 files changed, 94 insertions(+) create mode 100644 compiler-rt/test/ctx_profile/CMakeLists.txt create mode 100644 compiler-rt/test/ctx_profile/Unit/lit.site.cfg.py.in create mode 100644 compiler-rt/test/memprof/Unit/lit.site.cfg.py.in diff --git a/compiler-rt/test/CMakeLists.txt b/compiler-rt/test/CMakeLists.txt index edc007aaf477..8805cc8f798f 100644 --- a/compiler-rt/test/CMakeLists.txt +++ b/compiler-rt/test/CMakeLists.txt @@ -92,6 +92,9 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS) if(COMPILER_RT_BUILD_PROFILE AND COMPILER_RT_HAS_PROFILE) compiler_rt_test_runtime(profile) endif() + if(COMPILER_RT_BUILD_CTX_PROFILE) + compiler_rt_test_runtime(ctx_profile) + endif() if(COMPILER_RT_BUILD_MEMPROF) compiler_rt_test_runtime(memprof) endif() diff --git a/compiler-rt/test/ctx_profile/CMakeLists.txt b/compiler-rt/test/ctx_profile/CMakeLists.txt new file mode 100644 index 000000000000..23c6fb16ed1f --- /dev/null +++ b/compiler-rt/test/ctx_profile/CMakeLists.txt @@ -0,0 +1,21 @@ +set(CTX_PROFILE_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +set(CTX_PROFILE_TESTSUITES) + +# Add unit tests. +if(COMPILER_RT_INCLUDE_TESTS) + foreach(arch ${CTX_PROFILE_SUPPORTED_ARCH}) + string(TOUPPER ${arch} ARCH_UPPER_CASE) + set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/Unit/${CONFIG_NAME}/lit.site.cfg.py) + list(APPEND CTX_PROFILE_TEST_DEPS CtxProfileUnitTests) + list(APPEND CTX_PROFILE_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit/${CONFIG_NAME}) + endforeach() +endif() + +add_lit_testsuite(check-ctx_profile "Running the Contextual Profiler tests" + ${CTX_PROFILE_TESTSUITES} + DEPENDS ${CTX_PROFILE_TEST_DEPS}) +set_target_properties(check-ctx_profile PROPERTIES FOLDER "Compiler-RT Misc") diff --git a/compiler-rt/test/ctx_profile/Unit/lit.site.cfg.py.in b/compiler-rt/test/ctx_profile/Unit/lit.site.cfg.py.in new file mode 100644 index 000000000000..32a8c48e9c1c --- /dev/null +++ b/compiler-rt/test/ctx_profile/Unit/lit.site.cfg.py.in @@ -0,0 +1,27 @@ +@LIT_SITE_CFG_IN_HEADER@ + +import os +import platform +import re +import shlex + +# Load common config for all compiler-rt unit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/unittests/lit.common.unit.configured") + +# Setup config name. +config.name = 'CtxProfile-Unit' +config.target_arch = "@arch@" +assert config.target_arch == 'x86_64' + +config.test_exec_root = os.path.join("@COMPILER_RT_BINARY_DIR@", + "lib", "ctx_profile", "tests") + +config.test_source_root = config.test_exec_root + +# When LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=on, the initial value of +# config.compiler_rt_libdir (COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR) has the +# host triple as the trailing path component. The value is incorrect for i386 +# tests on x86_64 hosts and vice versa. But, since only x86_64 is enabled as +# target, and we don't support different environments for building and, +# respectivelly, running tests, we shouldn't see this case. +assert not config.enable_per_target_runtime_dir or config.target_arch == config.host_arch diff --git a/compiler-rt/test/memprof/CMakeLists.txt b/compiler-rt/test/memprof/CMakeLists.txt index 3f0ba3812485..fa6a4cd5f0b7 100644 --- a/compiler-rt/test/memprof/CMakeLists.txt +++ b/compiler-rt/test/memprof/CMakeLists.txt @@ -43,6 +43,19 @@ foreach(arch ${MEMPROF_TEST_ARCH}) ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) endforeach() +# Add unit tests. +if(COMPILER_RT_INCLUDE_TESTS) + foreach(arch ${MEMPROF_TEST_ARCH}) + string(TOUPPER ${arch} ARCH_UPPER_CASE) + set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/Unit/${CONFIG_NAME}/lit.site.cfg.py) + list(APPEND MEMPROF_TEST_DEPS MemProfUnitTests) + list(APPEND MEMPROF_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit/${CONFIG_NAME}) + endforeach() +endif() + add_lit_testsuite(check-memprof "Running the MemProfiler tests" ${MEMPROF_TESTSUITES} DEPENDS ${MEMPROF_TEST_DEPS}) diff --git a/compiler-rt/test/memprof/Unit/lit.site.cfg.py.in b/compiler-rt/test/memprof/Unit/lit.site.cfg.py.in new file mode 100644 index 000000000000..c968e403a44d --- /dev/null +++ b/compiler-rt/test/memprof/Unit/lit.site.cfg.py.in @@ -0,0 +1,30 @@ +@LIT_SITE_CFG_IN_HEADER@ + +import os +import platform +import re +import shlex + +# Load common config for all compiler-rt unit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/unittests/lit.common.unit.configured") + +# Setup config name. +config.name = 'MemProfiler-Unit' +config.target_arch = "@arch@" +assert config.target_arch == 'x86_64' + +config.test_exec_root = os.path.join("@COMPILER_RT_BINARY_DIR@", + "lib", "memprof", "tests") + +config.test_source_root = config.test_exec_root + +# When LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=on, the initial value of +# config.compiler_rt_libdir (COMPILER_RT_RESOLVED_LIBRARY_OUTPUT_DIR) has the +# host triple as the trailing path component. The value is incorrect for i386 +# tests on x86_64 hosts and vice versa. But, since only x86_64 is enabled as +# target, and we don't support different environments for building and, +# respectivelly, running tests, we shouldn't see this case. +assert not config.enable_per_target_runtime_dir or config.target_arch == config.host_arch + +if not config.parallelism_group: + config.parallelism_group = 'shadow-memory' \ No newline at end of file -- GitLab From d4338733e64f0463a22d98140dac5ecb0d381b6b Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 24 Apr 2024 13:37:35 -0700 Subject: [PATCH 018/733] [M68k] Fix killRegister use --- llvm/lib/Target/M68k/M68kISelLowering.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp index 63b32a619f35..62e4b36b5c9a 100644 --- a/llvm/lib/Target/M68k/M68kISelLowering.cpp +++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp @@ -3208,7 +3208,7 @@ M68kTargetLowering::EmitLoweredSelect(MachineInstr &MI, const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); MachineInstr *LastCCRSUser = CascadedCMOV ? CascadedCMOV : LastCMOV; - if (!LastCCRSUser->killsRegister(M68k::CCR) && + if (!LastCCRSUser->killsRegister(M68k::CCR, /*TRI=*/nullptr) && !checkAndUpdateCCRKill(LastCCRSUser, MBB, TRI)) { Copy0MBB->addLiveIn(M68k::CCR); SinkMBB->addLiveIn(M68k::CCR); -- GitLab From ea3eeb483fbbe09b9a66ed4c032cc7168f0265dd Mon Sep 17 00:00:00 2001 From: Peiming Liu Date: Wed, 24 Apr 2024 13:51:41 -0700 Subject: [PATCH 019/733] [mlir][sparse] fuse concat and extract_slice op if possible. (#89825) --- .../Transforms/SparseTensorRewriting.cpp | 86 ++++++++++++++++++- ...fuse_sparse_concat_with_extract_slice.mlir | 23 +++++ 2 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 mlir/test/Dialect/SparseTensor/fuse_sparse_concat_with_extract_slice.mlir diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp index 02375f54d715..5a39dfc62077 100644 --- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp +++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp @@ -209,6 +209,86 @@ static void concatSizesFromInputs(OpBuilder &builder, namespace { +/// TODO: move it to tensor dialect instead. +/// +/// Fold `tensor.concat` and `tensor.extract_slice` +/// +/// %concat = tensor.concat dim(2) %t0, %t1 +/// : (tensor<1x64x1xf32>, tensor<1x64x1xf32>) -> tensor<1x64x2xf32> +/// %extracted0 = tensor.extract_slice %concat[0, 0, 0][1, 64, 1][1, 1, 1] +/// : tensor<1x64x2xf32> to tensor<1x64x1xf32> +/// %extracted1 = tensor.extract_slice %concat[0, 0, 1][1, 64, 1][1, 1, 1] +/// : tensor<1x64x2xf32> to tensor<1x64x1xf32> +/// +/// Becomes +/// +/// %extract0, %extract1 = %t0, %t1 +struct FuseExtractSliceWithConcat + : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(tensor::ExtractSliceOp extractOp, + PatternRewriter &rewriter) const override { + auto concatOp = extractOp.getSource().getDefiningOp(); + if (!concatOp) + return failure(); + + Location loc = extractOp.getLoc(); + int64_t dim = concatOp.getDim(); + int64_t rank = extractOp.getResultType().getRank(); + + SmallVector srcStrides(rank, rewriter.getIndexAttr(1)); + SmallVector srcOffsets(rank, rewriter.getIndexAttr(0)); + + // Compute the partial sums for the slice offsets. + AffineExpr sum = rewriter.getAffineDimExpr(0); + SmallVector partialSums = {sum}; + SmallVector offsetStrides = {rewriter.getIndexAttr(0)}; + for (auto [idx, input] : + llvm::enumerate(concatOp.getInputs().drop_back())) { + sum = sum + rewriter.getAffineDimExpr(idx + 1); + partialSums.push_back(sum); + offsetStrides.push_back( + rewriter.createOrFold(loc, input, dim)); + } + auto partialSumMap = AffineMap::get(concatOp.getInputs().size(), 0, + partialSums, rewriter.getContext()); + SmallVector dimOffsets = + affine::makeComposedFoldedMultiResultAffineApply( + rewriter, loc, partialSumMap, offsetStrides); + + auto allEqual = [](ArrayRef lhs, ArrayRef rhs) { + for (auto [l, r] : llvm::zip(lhs, rhs)) { + std::optional staticVal = getConstantIntValue(l); + if (!staticVal.has_value() || staticVal != getConstantIntValue(r)) + return false; + } + return lhs.size() == rhs.size(); + }; + + for (auto [i, input, offset] : + llvm::enumerate(concatOp.getInputs(), dimOffsets)) { + SmallVector srcSizes = + tensor::getMixedSizes(rewriter, loc, input); + srcOffsets[dim] = offset; + + SmallVector dstSizes = extractOp.getMixedSizes(); + SmallVector dstOffsets = extractOp.getMixedOffsets(); + SmallVector dstStrides = extractOp.getMixedStrides(); + + if (allEqual(srcSizes, dstSizes) && allEqual(srcOffsets, dstOffsets) && + allEqual(srcStrides, dstStrides)) { + Value operand = concatOp.getOperand(i); + if (operand.getType() == extractOp.getResultType()) + rewriter.replaceOp(extractOp, operand); + break; + } + } + + return success(); + } +}; + /// Rewriting rule that converts direct yield of zero with initial allocation. struct FoldInvariantYield : public OpRewritePattern { public: @@ -1426,9 +1506,9 @@ struct OutRewriter : public OpRewritePattern { //===---------------------------------------------------------------------===// void mlir::populatePreSparsificationRewriting(RewritePatternSet &patterns) { - patterns.add( - patterns.getContext()); + patterns.add(patterns.getContext()); } void mlir::populateLowerSparseOpsToForeachPatterns(RewritePatternSet &patterns, diff --git a/mlir/test/Dialect/SparseTensor/fuse_sparse_concat_with_extract_slice.mlir b/mlir/test/Dialect/SparseTensor/fuse_sparse_concat_with_extract_slice.mlir new file mode 100644 index 000000000000..5d93301bc8ca --- /dev/null +++ b/mlir/test/Dialect/SparseTensor/fuse_sparse_concat_with_extract_slice.mlir @@ -0,0 +1,23 @@ +// RUN: mlir-opt %s --pre-sparsification-rewrite | FileCheck %s + +#CCCD = #sparse_tensor.encoding<{ map = (d0, d1, d2, d3) -> (d0 : compressed, d1 : compressed, d2 : compressed, d3 : dense) }> + + + +// CHECK-LABEL: func.func @fuse_concat_with_extract( +// CHECK-SAME: %[[VAL_0:.*0]]: tensor<128x32x32x1xf32, #sparse{{[0-9]*}}>, +// CHECK-SAME: %[[VAL_1:.*1]]: tensor<128x32x32x1xf32, #sparse{{[0-9]*}}>, +// CHECK-SAME: %[[VAL_2:.*2]]: tensor<128x32x32x1xf32, #sparse{{[0-9]*}}>) +// CHECK-NOT: tensor.concat +// CHECK-NOT: tensor.extract_slice +// CHECK: return %[[VAL_0]], %[[VAL_1]], %[[VAL_2]] +// CHECK: } +func.func @fuse_concat_with_extract(%t0 : tensor<128x32x32x1xf32, #CCCD>, + %t1 : tensor<128x32x32x1xf32, #CCCD>, + %t2 : tensor<128x32x32x1xf32, #CCCD>) -> (tensor<128x32x32x1xf32, #CCCD>, tensor<128x32x32x1xf32, #CCCD>, tensor<128x32x32x1xf32, #CCCD>) { + %concat = tensor.concat dim(3) %t0, %t1, %t2 : (tensor<128x32x32x1xf32, #CCCD>, tensor<128x32x32x1xf32, #CCCD>, tensor<128x32x32x1xf32, #CCCD>) -> tensor<128x32x32x3xf32, #CCCD> + %r0 = tensor.extract_slice %concat[0, 0, 0, 0] [128, 32, 32, 1] [1, 1, 1, 1] : tensor<128x32x32x3xf32, #CCCD> to tensor<128x32x32x1xf32, #CCCD> + %r1 = tensor.extract_slice %concat[0, 0, 0, 1] [128, 32, 32, 1] [1, 1, 1, 1] : tensor<128x32x32x3xf32, #CCCD> to tensor<128x32x32x1xf32, #CCCD> + %r2 = tensor.extract_slice %concat[0, 0, 0, 2] [128, 32, 32, 1] [1, 1, 1, 1] : tensor<128x32x32x3xf32, #CCCD> to tensor<128x32x32x1xf32, #CCCD> + return %r0, %r1, %r2 : tensor<128x32x32x1xf32, #CCCD>, tensor<128x32x32x1xf32, #CCCD>, tensor<128x32x32x1xf32, #CCCD> +} -- GitLab From 418e4b0c4ff2bc22dda318fce0293002a22fa76f Mon Sep 17 00:00:00 2001 From: Maksim Panchenko Date: Wed, 24 Apr 2024 14:03:33 -0700 Subject: [PATCH 020/733] [BOLT] Detect incorrect update of dynamic relocations (#89681) When we rewrite dynamic relocations, there could be cases where they reference code locations inside functions that were rewritten. When this happens, we need to precisely map old address to a new one. Until we can reliably perform the mapping, detect such condition and issue an error refusing to write a broken binary. --- bolt/lib/Rewrite/RewriteInstance.cpp | 11 +++++++++++ bolt/test/X86/indirect-goto-pie.test | 16 ++++++++++++++++ .../test/X86/shrinkwrapping-do-not-pessimize.s | 2 +- bolt/test/runtime/X86/Inputs/indirect_goto.c | 18 ------------------ bolt/test/runtime/X86/indirect-goto-pie.test | 10 ---------- 5 files changed, 28 insertions(+), 29 deletions(-) create mode 100644 bolt/test/X86/indirect-goto-pie.test delete mode 100644 bolt/test/runtime/X86/Inputs/indirect_goto.c delete mode 100644 bolt/test/runtime/X86/indirect-goto-pie.test diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 4e0096cf988a..21fa15b6a11f 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -5432,6 +5432,17 @@ uint64_t RewriteInstance::getNewFunctionOrDataAddress(uint64_t OldAddress) { if (BD && BD->isMoved()) return BD->getOutputAddress(); + if (const BinaryFunction *BF = + BC->getBinaryFunctionContainingAddress(OldAddress)) { + if (BF->isEmitted()) { + BC->errs() << "BOLT-ERROR: unable to get new address corresponding to " + "input address 0x" + << Twine::utohexstr(OldAddress) << " in function " << *BF + << ". Consider adding this function to --skip-funcs=...\n"; + exit(1); + } + } + return 0; } diff --git a/bolt/test/X86/indirect-goto-pie.test b/bolt/test/X86/indirect-goto-pie.test new file mode 100644 index 000000000000..039ff5c41d3d --- /dev/null +++ b/bolt/test/X86/indirect-goto-pie.test @@ -0,0 +1,16 @@ +# Check that llvm-bolt fails to process PIC binaries with computed goto, as the +# support is not there yet for correctly updating dynamic relocations +# referencing code inside functions. + +REQUIRES: x86_64-linux + +RUN: %clang %S/Inputs/indirect_goto.c -o %t -fpic -pie -Wl,-q +RUN: not llvm-bolt %t -o %t.bolt --relocs=1 --print-cfg --print-only=main \ +RUN: |& FileCheck %s + +# Check that processing works if main() is skipped. +RUN: llvm-bolt %t -o %t.bolt --relocs=1 --skip-funcs=main + +CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW + +CHECK: BOLT-ERROR: unable to get new address diff --git a/bolt/test/X86/shrinkwrapping-do-not-pessimize.s b/bolt/test/X86/shrinkwrapping-do-not-pessimize.s index a57131131423..3fdd5f5e38fe 100644 --- a/bolt/test/X86/shrinkwrapping-do-not-pessimize.s +++ b/bolt/test/X86/shrinkwrapping-do-not-pessimize.s @@ -53,6 +53,6 @@ end_if_1: .size _start, .-_start .data -rel: .quad end_if_1 +rel: .quad _start # CHECK: BOLT-INFO: Shrink wrapping moved 0 spills inserting load/stores and 0 spills inserting push/pops diff --git a/bolt/test/runtime/X86/Inputs/indirect_goto.c b/bolt/test/runtime/X86/Inputs/indirect_goto.c deleted file mode 100644 index b781e9e03b6d..000000000000 --- a/bolt/test/runtime/X86/Inputs/indirect_goto.c +++ /dev/null @@ -1,18 +0,0 @@ -int main(int argc, char *argv[]) { - static const void *T1[] = { &&L1, &&L2 }; - static const void *T2[] = { &&L2, &&L3 }; - - const void **T = (argc > 1) ? T1 : T2; - - int i = 0; - -L0: - goto *T[argc]; -L1: - ++i; -L2: - i++; -L3: - i++; - return i; -} diff --git a/bolt/test/runtime/X86/indirect-goto-pie.test b/bolt/test/runtime/X86/indirect-goto-pie.test deleted file mode 100644 index 76089fda3abf..000000000000 --- a/bolt/test/runtime/X86/indirect-goto-pie.test +++ /dev/null @@ -1,10 +0,0 @@ -# Check llvm-bolt processes binaries compiled from sources that use indirect goto. -REQUIRES: x86_64-linux - -RUN: %clang %S/Inputs/indirect_goto.c -o %t -fpic -pie -Wl,-q -RUN: llvm-bolt %t -o %t.bolt --relocs=1 --print-cfg --print-only=main \ -RUN: |& FileCheck %s -# The test fails as we don't update corresponding dynamic relocations. -RUN: not %t.bolt - -CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW -- GitLab From 82a8c1cf35e6794d4d1e56797d58abbed0112ad9 Mon Sep 17 00:00:00 2001 From: Peter Klausler <35819229+klausler@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:41:41 -0700 Subject: [PATCH 021/733] [flang][runtime] Support SELECTED_CHAR_KIND, SELECTED_LOGICAL_KIND (#89691) Add code to the runtime support library for the SELECTED_CHAR_KIND and SELECTED_LOGICAL_KIND intrinsic functions. These are usually used with constant folding in constant expressions, but the are available for use with dynamic arguments as well. Lowering support remains to be implemented. --- flang/include/flang/Runtime/numeric.h | 8 +++ flang/lib/Evaluate/type.cpp | 2 +- flang/runtime/numeric.cpp | 79 ++++++++++++++++++++++----- 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h index 3d9cb8b5b0ac..7d3f91360c8c 100644 --- a/flang/include/flang/Runtime/numeric.h +++ b/flang/include/flang/Runtime/numeric.h @@ -356,10 +356,18 @@ CppTypeFor RTDECL(Scale16)( CppTypeFor, std::int64_t); #endif +// SELECTED_CHAR_KIND +CppTypeFor RTDECL(SelectedCharKind)( + const char *, int, const char *, std::size_t); + // SELECTED_INT_KIND CppTypeFor RTDECL(SelectedIntKind)( const char *, int, void *, int); +// SELECTED_LOGICAL_KIND +CppTypeFor RTDECL(SelectedLogicalKind)( + const char *, int, void *, int); + // SELECTED_REAL_KIND CppTypeFor RTDECL(SelectedRealKind)( const char *, int, void *, int, void *, int, void *, int); diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp index a369e07f94a1..ee1e5b398d9b 100644 --- a/flang/lib/Evaluate/type.cpp +++ b/flang/lib/Evaluate/type.cpp @@ -731,7 +731,7 @@ bool SomeKind::operator==( return PointeeComparison(derivedTypeSpec_, that.derivedTypeSpec_); } -int SelectedCharKind(const std::string &s, int defaultKind) { // 16.9.168 +int SelectedCharKind(const std::string &s, int defaultKind) { // F'2023 16.9.180 auto lower{parser::ToLowerCaseLetters(s)}; auto n{lower.size()}; while (n > 0 && lower[0] == ' ') { diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp index abd3e500029f..52b5a56894d8 100644 --- a/flang/runtime/numeric.cpp +++ b/flang/runtime/numeric.cpp @@ -9,6 +9,7 @@ #include "flang/Runtime/numeric.h" #include "numeric-templates.h" #include "terminator.h" +#include "tools.h" #include "flang/Common/float128.h" #include #include @@ -18,30 +19,30 @@ namespace Fortran::runtime { template -inline RT_API_ATTRS RES getIntArgValue(const char *source, int line, void *arg, - int kind, std::int64_t defaultValue, int resKind) { +inline RT_API_ATTRS RES GetIntArgValue(const char *source, int line, + const void *arg, int kind, std::int64_t defaultValue, int resKind) { RES res; if (!arg) { res = static_cast(defaultValue); } else if (kind == 1) { res = static_cast( - *static_cast *>(arg)); + *static_cast *>(arg)); } else if (kind == 2) { res = static_cast( - *static_cast *>(arg)); + *static_cast *>(arg)); } else if (kind == 4) { res = static_cast( - *static_cast *>(arg)); + *static_cast *>(arg)); } else if (kind == 8) { res = static_cast( - *static_cast *>(arg)); + *static_cast *>(arg)); #ifdef __SIZEOF_INT128__ } else if (kind == 16) { if (resKind != 16) { Terminator{source, line}.Crash("Unexpected integer kind in runtime"); } res = static_cast( - *static_cast *>(arg)); + *static_cast *>(arg)); #endif } else { Terminator{source, line}.Crash("Unexpected integer kind in runtime"); @@ -112,6 +113,22 @@ inline RT_API_ATTRS CppTypeFor SelectedIntKind(T x) { return -1; } +// SELECTED_LOGICAL_KIND (F'2023 16.9.182) +template +inline RT_API_ATTRS CppTypeFor SelectedLogicalKind( + T x) { + if (x <= 2) { + return 1; + } else if (x <= 4) { + return 2; + } else if (x <= 9) { + return 4; + } else if (x <= 18) { + return 8; + } + return -1; +} + // SELECTED_REAL_KIND (16.9.170) template inline RT_API_ATTRS CppTypeFor SelectedRealKind( @@ -717,40 +734,72 @@ CppTypeFor RTDEF(Scale10)( } #endif +// SELECTED_CHAR_KIND +CppTypeFor RTDEF(SelectedCharKind)( + const char *source, int line, const char *x, std::size_t length) { + static const char *keywords[]{ + "ASCII", "DEFAULT", "UCS-2", "ISO_10646", "UCS-4", nullptr}; + switch (IdentifyValue(x, length, keywords)) { + case 0: // ASCII + case 1: // DEFAULT + return 1; + case 2: // UCS-2 + return 2; + case 3: // ISO_10646 + case 4: // UCS-4 + return 4; + default: + return -1; + } +} // SELECTED_INT_KIND CppTypeFor RTDEF(SelectedIntKind)( const char *source, int line, void *x, int xKind) { #ifdef __SIZEOF_INT128__ CppTypeFor r = - getIntArgValue>( + GetIntArgValue>( source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 16); #else - std::int64_t r = getIntArgValue( + std::int64_t r = GetIntArgValue( source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8); #endif return SelectedIntKind(r); } +// SELECTED_LOGICAL_KIND +CppTypeFor RTDEF(SelectedLogicalKind)( + const char *source, int line, void *x, int xKind) { +#ifdef __SIZEOF_INT128__ + CppTypeFor r = + GetIntArgValue>( + source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 16); +#else + std::int64_t r = GetIntArgValue( + source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8); +#endif + return SelectedLogicalKind(r); +} + // SELECTED_REAL_KIND CppTypeFor RTDEF(SelectedRealKind)(const char *source, int line, void *precision, int pKind, void *range, int rKind, void *radix, int dKind) { #ifdef __SIZEOF_INT128__ CppTypeFor p = - getIntArgValue>( + GetIntArgValue>( source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 16); CppTypeFor r = - getIntArgValue>( + GetIntArgValue>( source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 16); CppTypeFor d = - getIntArgValue>( + GetIntArgValue>( source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 16); #else - std::int64_t p = getIntArgValue( + std::int64_t p = GetIntArgValue( source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 8); - std::int64_t r = getIntArgValue( + std::int64_t r = GetIntArgValue( source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 8); - std::int64_t d = getIntArgValue( + std::int64_t d = GetIntArgValue( source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 8); #endif return SelectedRealKind(p, r, d); -- GitLab From 186952f0176fda0f73989c2c9335faf26632e112 Mon Sep 17 00:00:00 2001 From: Chao Chen <116223022+chencha3@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:47:54 -0500 Subject: [PATCH 022/733] [MLIR][XeGPU] Fix Bot failure for #88973 (#89991) --- mlir/lib/Dialect/XeGPU/IR/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/mlir/lib/Dialect/XeGPU/IR/CMakeLists.txt b/mlir/lib/Dialect/XeGPU/IR/CMakeLists.txt index 617c89a84ee0..a0ce7f9706ce 100644 --- a/mlir/lib/Dialect/XeGPU/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/XeGPU/IR/CMakeLists.txt @@ -11,6 +11,7 @@ add_mlir_dialect_library(MLIRXeGPUDialect MLIRXeGPUEnumsIncGen LINK_LIBS PUBLIC + MLIRArithDialect MLIRDialectUtils MLIRIR MLIRViewLikeInterface -- GitLab From 69bde04230d45f9bb54cc10af1a6d19cf565dd9e Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Wed, 24 Apr 2024 14:49:46 -0700 Subject: [PATCH 023/733] split XeGPU enums into a separate build rule (#89997) Fixes the bazel build. Note the addition of the Arith dependency created duplicate arith enum declarations in the two dialects, so it had to be spit into its own build rule. This matches what the cmake build does for this dialect. --- .../llvm-project-overlay/mlir/BUILD.bazel | 51 +++++++++++++++---- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index 63b24b9f46b2..05f096163fdd 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -5,8 +5,8 @@ # Description: # The MLIR "Multi-Level Intermediate Representation" Compiler Infrastructure -load("@bazel_skylib//rules:expand_template.bzl", "expand_template") load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") +load("@bazel_skylib//rules:expand_template.bzl", "expand_template") load( ":build_defs.bzl", "cc_headers_only", @@ -3652,14 +3652,6 @@ gentbl_cc_library( ], "include/mlir/Dialect/XeGPU/IR/XeGPUTypes.cpp.inc", ), - ( - ["-gen-enum-decls"], - "include/mlir/Dialect/XeGPU/IR/XeGPUEnums.h.inc", - ), - ( - ["-gen-enum-defs"], - "include/mlir/Dialect/XeGPU/IR/XeGPUEnums.cpp.inc", - ), ( [ "-gen-attrdef-decls", @@ -3677,7 +3669,44 @@ gentbl_cc_library( ], tblgen = ":mlir-tblgen", td_file = "include/mlir/Dialect/XeGPU/IR/XeGPU.td", - deps = [":XeGPUTdFiles"], + deps = [ + ":ArithOpsTdFiles", + ":XeGPUTdFiles", + ], +) + +td_library( + name = "XeGPUAttrTdFiles", + srcs = [ + "include/mlir/Dialect/XeGPU/IR/XeGPUAttrs.td", + "include/mlir/Dialect/XeGPU/IR/XeGPUDialect.td", + ], + includes = ["include"], + deps = [ + ":BuiltinDialectTdFiles", + ":OpBaseTdFiles", + ":ShapedOpInterfacesTdFiles", + ":ViewLikeInterfaceTdFiles", + ], +) + +# Separated from the XeGPUIncGen target because the enum declaration causes +# duplicate declarations with the Arith enums. +gentbl_cc_library( + name = "XeGPUEnumsIncGen", + tbl_outs = [ + ( + ["-gen-enum-decls"], + "include/mlir/Dialect/XeGPU/IR/XeGPUEnums.h.inc", + ), + ( + ["-gen-enum-defs"], + "include/mlir/Dialect/XeGPU/IR/XeGPUEnums.cpp.inc", + ), + ], + tblgen = ":mlir-tblgen", + td_file = "include/mlir/Dialect/XeGPU/IR/XeGPUAttrs.td", + deps = [":XeGPUAttrTdFiles"], ) cc_library( @@ -3689,12 +3718,14 @@ cc_library( hdrs = ["include/mlir/Dialect/XeGPU/IR/XeGPU.h"], includes = ["include"], deps = [ + ":ArithDialect", ":BytecodeOpInterface", ":DialectUtils", ":IR", ":ShapedOpInterfaces", ":SideEffectInterfaces", ":ViewLikeInterface", + ":XeGPUEnumsIncGen", ":XeGPUIncGen", "//llvm:Support", ], -- GitLab From 29c98e59cd84ed5c8dde27876779d6b8830ccac5 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Wed, 24 Apr 2024 14:42:07 -0700 Subject: [PATCH 024/733] Revert "[Inline][Cloning] Defer simplification after phi-nodes resolution" #87963 Reopens #87534. Breaks multiple bots: https://lab.llvm.org/buildbot/#/builders/168/builds/20028 https://lab.llvm.org/buildbot/#/builders/74/builds/27773 And reproducer in a61f9fe31750cee65c726fb51f1b14e31e177258. This reverts commit a61f9fe31750cee65c726fb51f1b14e31e177258. --- llvm/lib/Transforms/Utils/CloneFunction.cpp | 92 ++++++++++++------- .../Inline/inline-deferred-instsimplify.ll | 6 +- .../Inline/prof-update-sample-alwaysinline.ll | 1 + .../Transforms/Inline/prof-update-sample.ll | 1 + 4 files changed, 61 insertions(+), 39 deletions(-) diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index 42e648484416..3eac726994ae 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -14,7 +14,6 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/DomTreeUpdater.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" @@ -541,13 +540,18 @@ void PruningFunctionCloner::CloneBlock( RemapInstruction(NewInst, VMap, ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges); - // Eagerly constant fold the newly cloned instruction. If successful, add - // a mapping to the new value. Non-constant operands may be incomplete at - // this stage, thus instruction simplification is performed after - // processing phi-nodes. - if (Value *V = ConstantFoldInstruction( - NewInst, BB->getModule()->getDataLayout())) { - if (isInstructionTriviallyDead(NewInst)) { + // If we can simplify this instruction to some other value, simply add + // a mapping to that value rather than inserting a new instruction into + // the basic block. + if (Value *V = + simplifyInstruction(NewInst, BB->getModule()->getDataLayout())) { + // On the off-chance that this simplifies to an instruction in the old + // function, map it back into the new function. + if (NewFunc != OldFunc) + if (Value *MappedV = VMap.lookup(V)) + V = MappedV; + + if (!NewInst->mayHaveSideEffects()) { VMap[&*II] = V; NewInst->eraseFromParent(); continue; @@ -819,34 +823,52 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, } } - // As phi-nodes have been now remapped, allow incremental simplification of - // newly-cloned instructions. + // Make a second pass over the PHINodes now that all of them have been + // remapped into the new function, simplifying the PHINode and performing any + // recursive simplifications exposed. This will transparently update the + // WeakTrackingVH in the VMap. Notably, we rely on that so that if we coalesce + // two PHINodes, the iteration over the old PHIs remains valid, and the + // mapping will just map us to the new node (which may not even be a PHI + // node). const DataLayout &DL = NewFunc->getParent()->getDataLayout(); - for (const auto &BB : *OldFunc) { - for (const auto &I : BB) { - auto *NewI = dyn_cast_or_null(VMap.lookup(&I)); - if (!NewI) - continue; - - // Skip over non-intrinsic callsites, we don't want to remove any nodes - // from the CGSCC. - CallBase *CB = dyn_cast(NewI); - if (CB && CB->getCalledFunction() && - !CB->getCalledFunction()->isIntrinsic()) - continue; - - if (Value *V = simplifyInstruction(NewI, DL)) { - NewI->replaceAllUsesWith(V); - - if (isInstructionTriviallyDead(NewI)) { - NewI->eraseFromParent(); - } else { - // Did not erase it? Restore the new instruction into VMap previously - // dropped by `ValueIsRAUWd`. - VMap[&I] = NewI; - } - } - } + SmallSetVector Worklist; + for (unsigned Idx = 0, Size = PHIToResolve.size(); Idx != Size; ++Idx) + if (isa(VMap[PHIToResolve[Idx]])) + Worklist.insert(PHIToResolve[Idx]); + + // Note that we must test the size on each iteration, the worklist can grow. + for (unsigned Idx = 0; Idx != Worklist.size(); ++Idx) { + const Value *OrigV = Worklist[Idx]; + auto *I = dyn_cast_or_null(VMap.lookup(OrigV)); + if (!I) + continue; + + // Skip over non-intrinsic callsites, we don't want to remove any nodes from + // the CGSCC. + CallBase *CB = dyn_cast(I); + if (CB && CB->getCalledFunction() && + !CB->getCalledFunction()->isIntrinsic()) + continue; + + // See if this instruction simplifies. + Value *SimpleV = simplifyInstruction(I, DL); + if (!SimpleV) + continue; + + // Stash away all the uses of the old instruction so we can check them for + // recursive simplifications after a RAUW. This is cheaper than checking all + // uses of To on the recursive step in most cases. + for (const User *U : OrigV->users()) + Worklist.insert(cast(U)); + + // Replace the instruction with its simplified value. + I->replaceAllUsesWith(SimpleV); + + // If the original instruction had no side effects, remove it. + if (isInstructionTriviallyDead(I)) + I->eraseFromParent(); + else + VMap[OrigV] = I; } // Remap debug intrinsic operands now that all values have been mapped. diff --git a/llvm/test/Transforms/Inline/inline-deferred-instsimplify.ll b/llvm/test/Transforms/Inline/inline-deferred-instsimplify.ll index f02d03688f03..4a9c576f0271 100644 --- a/llvm/test/Transforms/Inline/inline-deferred-instsimplify.ll +++ b/llvm/test/Transforms/Inline/inline-deferred-instsimplify.ll @@ -38,6 +38,8 @@ store_ptr_in_gvar: ; preds = %entry check_pointers_are_equal: ; preds = %store_ptr_in_gvar, %entry %phi = phi ptr [ %ptr, %store_ptr_in_gvar ], [ @other_g_var, %entry ] +; FIXME: While inlining, the following is miscompiled to i1 false, +; as %ptr in the phi-node is not taken into account. %.not1 = icmp eq ptr %phi, %ptr br i1 %.not1, label %return, label %abort @@ -62,13 +64,9 @@ define i32 @main() { ; CHECK-NEXT: br label [[CHECK_POINTERS_ARE_EQUAL_I]] ; CHECK: check_pointers_are_equal.i: ; CHECK-NEXT: [[PHI_I:%.*]] = phi ptr [ [[G_VAR]], [[STORE_PTR_IN_GVAR_I]] ], [ @other_g_var, [[TMP0:%.*]] ] -; CHECK-NEXT: [[DOTNOT1_I:%.*]] = icmp eq ptr [[PHI_I]], [[G_VAR]] -; CHECK-NEXT: br i1 [[DOTNOT1_I]], label [[CALLEE_EXIT:%.*]], label [[ABORT_I:%.*]] -; CHECK: abort.i: ; CHECK-NEXT: call void @abort() ; CHECK-NEXT: unreachable ; CHECK: callee.exit: -; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 20, ptr [[G_VAR]]) ; CHECK-NEXT: ret i32 0 ; call void @callee(ptr noundef byval(%struct.a) align 8 @g_var) diff --git a/llvm/test/Transforms/Inline/prof-update-sample-alwaysinline.ll b/llvm/test/Transforms/Inline/prof-update-sample-alwaysinline.ll index 8af4d89663a4..d6b771e2629d 100644 --- a/llvm/test/Transforms/Inline/prof-update-sample-alwaysinline.ll +++ b/llvm/test/Transforms/Inline/prof-update-sample-alwaysinline.ll @@ -53,6 +53,7 @@ define void @caller() { !18 = !{!"VP", i32 0, i64 140, i64 111, i64 80, i64 222, i64 40, i64 333, i64 20} attributes #0 = { alwaysinline } ; CHECK: ![[ENTRY_COUNT]] = !{!"function_entry_count", i64 600} +; CHECK: ![[COUNT_CALLEE1]] = !{!"branch_weights", i32 2000} ; CHECK: ![[COUNT_CALLEE]] = !{!"branch_weights", i32 1200} ; CHECK: ![[COUNT_IND_CALLEE]] = !{!"VP", i32 0, i64 84, i64 111, i64 48, i64 222, i64 24, i64 333, i64 12} ; CHECK: ![[COUNT_CALLER]] = !{!"branch_weights", i32 800} diff --git a/llvm/test/Transforms/Inline/prof-update-sample.ll b/llvm/test/Transforms/Inline/prof-update-sample.ll index e09b859b6981..6cdd70e84e0c 100644 --- a/llvm/test/Transforms/Inline/prof-update-sample.ll +++ b/llvm/test/Transforms/Inline/prof-update-sample.ll @@ -52,6 +52,7 @@ define void @caller() { !17 = !{!"branch_weights", i32 400} !18 = !{!"VP", i32 0, i64 140, i64 111, i64 80, i64 222, i64 40, i64 333, i64 20} ; CHECK: ![[ENTRY_COUNT]] = !{!"function_entry_count", i64 600} +; CHECK: ![[COUNT_CALLEE1]] = !{!"branch_weights", i32 2000} ; CHECK: ![[COUNT_CALLEE]] = !{!"branch_weights", i32 1200} ; CHECK: ![[COUNT_IND_CALLEE]] = !{!"VP", i32 0, i64 84, i64 111, i64 48, i64 222, i64 24, i64 333, i64 12} ; CHECK: ![[COUNT_CALLER]] = !{!"branch_weights", i32 800} -- GitLab From c3def59d0f28edf32eb43236db88f21321f36dca Mon Sep 17 00:00:00 2001 From: Peter Klausler <35819229+klausler@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:57:00 -0700 Subject: [PATCH 025/733] [flang] Fix bogus error about duplicate binding names (#89786) Don't call SetBindNameOn() from DeclareUnknownEntity() unless there is an explicit BIND(C) attribute. Fixes https://github.com/llvm/llvm-project/issues/89439 and https://github.com/llvm/llvm-project/issues/89558. --- flang/lib/Semantics/resolve-names.cpp | 15 +++++++++------ flang/test/Semantics/declarations03.f90 | 13 +++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index b941f257a95e..c21cf1bf4d7d 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -1779,7 +1779,6 @@ void AttrsVisitor::SetBindNameOn(Symbol &symbol) { !symbol.attrs().test(Attr::BIND_C)) { return; } - std::optional label{ evaluate::GetScalarConstantValue(bindName_)}; // 18.9.2(2): discard leading and trailing blanks @@ -1798,16 +1797,18 @@ void AttrsVisitor::SetBindNameOn(Symbol &symbol) { } else { label = symbol.name().ToString(); } - // Check if a symbol has two Bind names. + // Checks whether a symbol has two Bind names. std::string oldBindName; - if (symbol.GetBindName()) { - oldBindName = *symbol.GetBindName(); + if (const auto *bindName{symbol.GetBindName()}) { + oldBindName = *bindName; } symbol.SetBindName(std::move(*label)); if (!oldBindName.empty()) { if (const std::string * newBindName{symbol.GetBindName()}) { if (oldBindName != *newBindName) { - Say(symbol.name(), "The entity '%s' has multiple BIND names"_err_en_US); + Say(symbol.name(), + "The entity '%s' has multiple BIND names ('%s' and '%s')"_err_en_US, + symbol.name(), oldBindName, *newBindName); } } } @@ -4986,7 +4987,9 @@ Symbol &DeclarationVisitor::DeclareUnknownEntity( if (symbol.attrs().test(Attr::EXTERNAL)) { ConvertToProcEntity(symbol); } - SetBindNameOn(symbol); + if (attrs.test(Attr::BIND_C)) { + SetBindNameOn(symbol); + } return symbol; } } diff --git a/flang/test/Semantics/declarations03.f90 b/flang/test/Semantics/declarations03.f90 index 3459b2287b2b..65b07e7d5c65 100644 --- a/flang/test/Semantics/declarations03.f90 +++ b/flang/test/Semantics/declarations03.f90 @@ -19,7 +19,7 @@ module m common /blk4/ w bind(c, name="cc") :: t2, /blk4/ - !ERROR: The entity 'blk5' has multiple BIND names + !ERROR: The entity 'blk5' has multiple BIND names ('dd' and 'ee') common /blk5/ i bind(c, name="dd") :: /blk5/ bind(c, name="ee") :: /blk5/ @@ -29,7 +29,7 @@ module m bind(c, name="ff") :: /blk6/ bind(c, name="ff") :: /blk7/ - !ERROR: The entity 's1' has multiple BIND names + !ERROR: The entity 's1' has multiple BIND names ('gg' and 'hh') integer :: s1 bind(c, name="gg") :: s1 !ERROR: BIND_C attribute was already specified on 's1' @@ -40,12 +40,12 @@ module m bind(c, name="ii") :: s2 bind(c, name="ii") :: s3 - !ERROR: The entity 's4' has multiple BIND names + !ERROR: The entity 's4' has multiple BIND names ('ss1' and 'jj') integer, bind(c, name="ss1") :: s4 !ERROR: BIND_C attribute was already specified on 's4' bind(c, name="jj") :: s4 - !ERROR: The entity 's5' has multiple BIND names + !ERROR: The entity 's5' has multiple BIND names ('kk' and 'ss2') bind(c, name="kk") :: s5 !ERROR: BIND_C attribute was already specified on 's5' integer, bind(c, name="ss2") :: s5 @@ -72,3 +72,8 @@ module b !ERROR: Two entities have the same global name 'int' integer, bind(c, name="int") :: i end module + +module c + bind(c, name = "AAA") a + integer aaa ! ensure no bogus error about multiple binding names +end module -- GitLab From 1b232fa0e9864dde230db8da82a906c588baf792 Mon Sep 17 00:00:00 2001 From: Jeff Niu Date: Wed, 24 Apr 2024 14:58:37 -0700 Subject: [PATCH 026/733] [mlir][ods] Allow sharding of op definitions (#89423) Adds an option to `mlir-tblgen -gen-op-defs` `op-shard-count=N` that divides the op class definitions and op list into N segments, e.g. ``` // mlir-tblgen -gen-op-defs -op-shard-count=2 void FooDialect::initialize() { addOperations< >(); addOperations< >(); } ``` When split across multiple source files, this can help significantly improve dialect compile time for dialects with a large opset. --- mlir/CMakeLists.txt | 3 + mlir/cmake/modules/AddMLIR.cmake | 38 ++++ mlir/cmake/modules/CMakeLists.txt | 2 + mlir/cmake/modules/MLIRConfig.cmake.in | 1 + mlir/include/mlir/TableGen/CodeGenHelpers.h | 12 +- mlir/lib/TableGen/CodeGenHelpers.cpp | 15 +- mlir/test/mlir-tblgen/shard-op-defs.td | 33 ++++ mlir/tools/mlir-src-sharder/CMakeLists.txt | 14 ++ .../mlir-src-sharder/mlir-src-sharder.cpp | 114 ++++++++++++ mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 164 ++++++++++++++---- mlir/tools/mlir-tblgen/OpGenHelpers.cpp | 25 ++- mlir/tools/mlir-tblgen/OpGenHelpers.h | 5 + .../llvm-project-overlay/mlir/BUILD.bazel | 9 + .../llvm-project-overlay/mlir/tblgen.bzl | 133 ++++++++++++++ 14 files changed, 519 insertions(+), 49 deletions(-) create mode 100644 mlir/test/mlir-tblgen/shard-op-defs.td create mode 100644 mlir/tools/mlir-src-sharder/CMakeLists.txt create mode 100644 mlir/tools/mlir-src-sharder/mlir-src-sharder.cpp diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt index 5c4301af040b..4c0ef8387b8d 100644 --- a/mlir/CMakeLists.txt +++ b/mlir/CMakeLists.txt @@ -185,10 +185,13 @@ include_directories( ${MLIR_INCLUDE_DIR}) add_subdirectory(tools/mlir-linalg-ods-gen) add_subdirectory(tools/mlir-pdll) add_subdirectory(tools/mlir-tblgen) +add_subdirectory(tools/mlir-src-sharder) set(MLIR_TABLEGEN_EXE "${MLIR_TABLEGEN_EXE}" CACHE INTERNAL "") set(MLIR_TABLEGEN_TARGET "${MLIR_TABLEGEN_TARGET}" CACHE INTERNAL "") set(MLIR_PDLL_TABLEGEN_EXE "${MLIR_PDLL_TABLEGEN_EXE}" CACHE INTERNAL "") set(MLIR_PDLL_TABLEGEN_TARGET "${MLIR_PDLL_TABLEGEN_TARGET}" CACHE INTERNAL "") +set(MLIR_SRC_SHARDER_TABLEGEN_EXE "${MLIR_SRC_SHARDER_TABLEGEN_EXE}" CACHE INTERNAL "") +set(MLIR_SRC_SHARDER_TABLEGEN_TARGET "${MLIR_SRC_SHARDER_TABLEGEN_TARGET}" CACHE INTERNAL "") add_subdirectory(include/mlir) add_subdirectory(lib) diff --git a/mlir/cmake/modules/AddMLIR.cmake b/mlir/cmake/modules/AddMLIR.cmake index 1d2ed748bc2f..afb74fb2d000 100644 --- a/mlir/cmake/modules/AddMLIR.cmake +++ b/mlir/cmake/modules/AddMLIR.cmake @@ -5,6 +5,28 @@ function(mlir_tablegen ofn) tablegen(MLIR ${ARGV}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) + + # Get the current set of include paths for this td file. + cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN}) + get_directory_property(tblgen_includes INCLUDE_DIRECTORIES) + list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES}) + # Filter out any empty include items. + list(REMOVE_ITEM tblgen_includes "") + + # Build the absolute path for the current input file. + if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) + set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) + else() + set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS}) + endif() + + # Append the includes used for this file to the tablegen_compile_commands + # file. + file(APPEND ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml + "--- !FileInfo:\n" + " filepath: \"${LLVM_TARGET_DEFINITIONS_ABSOLUTE}\"\n" + " includes: \"${CMAKE_CURRENT_SOURCE_DIR};${tblgen_includes}\"\n" + ) endfunction() # Clear out any pre-existing compile_commands file before processing. This @@ -149,6 +171,22 @@ function(add_mlir_dialect dialect dialect_namespace) add_dependencies(mlir-headers MLIR${dialect}IncGen) endfunction() +# Declare sharded dialect operation declarations and definitions +function(add_sharded_ops ops_target shard_count) + set(LLVM_TARGET_DEFINITIONS ${ops_target}.td) + mlir_tablegen(${ops_target}.h.inc -gen-op-decls -op-shard-count=${shard_count}) + mlir_tablegen(${ops_target}.cpp.inc -gen-op-defs -op-shard-count=${shard_count}) + set(LLVM_TARGET_DEFINITIONS ${ops_target}.cpp) + foreach(index RANGE ${shard_count}) + set(SHARDED_SRC ${ops_target}.${index}.cpp) + list(APPEND SHARDED_SRCS ${SHARDED_SRC}) + tablegen(MLIR_SRC_SHARDER ${SHARDED_SRC} -op-shard-index=${index}) + set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${SHARDED_SRC}) + endforeach() + add_public_tablegen_target(MLIR${ops_target}ShardGen) + set(SHARDED_SRCS ${SHARDED_SRCS} PARENT_SCOPE) +endfunction() + # Declare a dialect in the include directory function(add_mlir_interface interface) set(LLVM_TARGET_DEFINITIONS ${interface}.td) diff --git a/mlir/cmake/modules/CMakeLists.txt b/mlir/cmake/modules/CMakeLists.txt index 8d2904ef46df..3ac1c79b090e 100644 --- a/mlir/cmake/modules/CMakeLists.txt +++ b/mlir/cmake/modules/CMakeLists.txt @@ -39,6 +39,7 @@ set(MLIR_CONFIG_INCLUDE_DIRS # Refer to the best host mlir-tbgen, which might be a host-optimized version set(MLIR_CONFIG_TABLEGEN_EXE "${MLIR_TABLEGEN_EXE}") set(MLIR_CONFIG_PDLL_TABLEGEN_EXE "${MLIR_PDLL_TABLEGEN_EXE}") +set(MLIR_CONFIG_SRC_SHARDER_TABLEGEN_EXE "${MLIR_SRC_SHARDER_TABLEGEN_EXE}") configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/MLIRConfig.cmake.in @@ -77,6 +78,7 @@ set(MLIR_CONFIG_INCLUDE_DIRS # if we're building with a host-optimized mlir-tblgen (with LLVM_OPTIMIZED_TABLEGEN). set(MLIR_CONFIG_TABLEGEN_EXE mlir-tblgen) set(MLIR_CONFIG_PDLL_TABLEGEN_EXE mlir-pdll) +set(MLIR_CONFIG_SRC_SHARDER_TABLEGEN_EXE mlir-src-sharder) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/MLIRConfig.cmake.in diff --git a/mlir/cmake/modules/MLIRConfig.cmake.in b/mlir/cmake/modules/MLIRConfig.cmake.in index d4da3cd98cce..7076d94a32f2 100644 --- a/mlir/cmake/modules/MLIRConfig.cmake.in +++ b/mlir/cmake/modules/MLIRConfig.cmake.in @@ -11,6 +11,7 @@ set(MLIR_CMAKE_DIR "@MLIR_CONFIG_CMAKE_DIR@") set(MLIR_INCLUDE_DIRS "@MLIR_CONFIG_INCLUDE_DIRS@") set(MLIR_TABLEGEN_EXE "@MLIR_CONFIG_TABLEGEN_EXE@") set(MLIR_PDLL_TABLEGEN_EXE "@MLIR_CONFIG_PDLL_TABLEGEN_EXE@") +set(MLIR_SRC_SHARDER_TABLEGEN_EXE "@MLIR_CONFIG_SRC_SHARDER_TABLEGEN_EXE@") set(MLIR_INSTALL_AGGREGATE_OBJECTS "@MLIR_INSTALL_AGGREGATE_OBJECTS@") set(MLIR_ENABLE_BINDINGS_PYTHON "@MLIR_ENABLE_BINDINGS_PYTHON@") set(MLIR_ENABLE_EXECUTION_ENGINE "@MLIR_ENABLE_EXECUTION_ENGINE@") diff --git a/mlir/include/mlir/TableGen/CodeGenHelpers.h b/mlir/include/mlir/TableGen/CodeGenHelpers.h index dd17a44c889b..c263c69c53d1 100644 --- a/mlir/include/mlir/TableGen/CodeGenHelpers.h +++ b/mlir/include/mlir/TableGen/CodeGenHelpers.h @@ -99,8 +99,14 @@ private: /// class StaticVerifierFunctionEmitter { public: + /// Create a constraint uniquer with a unique prefix derived from the record + /// keeper with an optional tag. StaticVerifierFunctionEmitter(raw_ostream &os, - const llvm::RecordKeeper &records); + const llvm::RecordKeeper &records, + StringRef tag = ""); + + /// Collect and unique all the constraints used by operations. + void collectOpConstraints(ArrayRef opDefs); /// Collect and unique all compatible type, attribute, successor, and region /// constraints from the operations in the file and emit them at the top of @@ -108,7 +114,7 @@ public: /// /// Constraints that do not meet the restriction that they can only reference /// `$_self` and `$_op` are not uniqued. - void emitOpConstraints(ArrayRef opDefs, bool emitDecl); + void emitOpConstraints(ArrayRef opDefs); /// Unique all compatible type and attribute constraints from a pattern file /// and emit them at the top of the generated file. @@ -177,8 +183,6 @@ private: /// Emit pattern constraints. void emitPatternConstraints(); - /// Collect and unique all the constraints used by operations. - void collectOpConstraints(ArrayRef opDefs); /// Collect and unique all pattern constraints. void collectPatternConstraints(ArrayRef constraints); diff --git a/mlir/lib/TableGen/CodeGenHelpers.cpp b/mlir/lib/TableGen/CodeGenHelpers.cpp index d906de6b56af..59865146e20b 100644 --- a/mlir/lib/TableGen/CodeGenHelpers.cpp +++ b/mlir/lib/TableGen/CodeGenHelpers.cpp @@ -24,7 +24,8 @@ using namespace mlir::tblgen; /// Generate a unique label based on the current file name to prevent name /// collisions if multiple generated files are included at once. -static std::string getUniqueOutputLabel(const llvm::RecordKeeper &records) { +static std::string getUniqueOutputLabel(const llvm::RecordKeeper &records, + StringRef tag) { // Use the input file name when generating a unique name. std::string inputFilename = records.getInputFilename(); @@ -33,7 +34,7 @@ static std::string getUniqueOutputLabel(const llvm::RecordKeeper &records) { nameRef.consume_back(".td"); // Sanitize any invalid characters. - std::string uniqueName; + std::string uniqueName(tag); for (char c : nameRef) { if (llvm::isAlnum(c) || c == '_') uniqueName.push_back(c); @@ -44,15 +45,11 @@ static std::string getUniqueOutputLabel(const llvm::RecordKeeper &records) { } StaticVerifierFunctionEmitter::StaticVerifierFunctionEmitter( - raw_ostream &os, const llvm::RecordKeeper &records) - : os(os), uniqueOutputLabel(getUniqueOutputLabel(records)) {} + raw_ostream &os, const llvm::RecordKeeper &records, StringRef tag) + : os(os), uniqueOutputLabel(getUniqueOutputLabel(records, tag)) {} void StaticVerifierFunctionEmitter::emitOpConstraints( - ArrayRef opDefs, bool emitDecl) { - collectOpConstraints(opDefs); - if (emitDecl) - return; - + ArrayRef opDefs) { NamespaceEmitter namespaceEmitter(os, Operator(*opDefs[0]).getCppNamespace()); emitTypeConstraints(); emitAttrConstraints(); diff --git a/mlir/test/mlir-tblgen/shard-op-defs.td b/mlir/test/mlir-tblgen/shard-op-defs.td new file mode 100644 index 000000000000..84ac6b0fbe9e --- /dev/null +++ b/mlir/test/mlir-tblgen/shard-op-defs.td @@ -0,0 +1,33 @@ +// RUN: mlir-tblgen -gen-op-defs -op-shard-count=2 -I %S/../../include %s | FileCheck %s --check-prefix=DEFS +// RUN: mlir-tblgen -gen-op-decls -op-shard-count=2 -I %S/../../include %s | FileCheck %s --check-prefix=DECLS + +include "mlir/IR/OpBase.td" + +def Test_Dialect : Dialect { + let name = "test"; + let cppNamespace = "test"; +} + +class Test_Op traits = []> + : Op; + +def OpA : Test_Op<"a">; +def OpB : Test_Op<"b">; +def OpC : Test_Op<"c">; + +// DECLS: OpA +// DECLS: OpB +// DECLS: OpC +// DECLS: registerTestDialectOperations( +// DECLS: registerTestDialectOperations0( +// DECLS: registerTestDialectOperations1( + +// DEFS-LABEL: GET_OP_DEFS_0 +// DEFS: void test::registerTestDialectOperations( +// DEFS: void test::registerTestDialectOperations0( +// DEFS: OpAAdaptor +// DEFS: OpBAdaptor + +// DEFS-LABEL: GET_OP_DEFS_1 +// DEFS: void test::registerTestDialectOperations1( +// DEFS: OpCAdaptor diff --git a/mlir/tools/mlir-src-sharder/CMakeLists.txt b/mlir/tools/mlir-src-sharder/CMakeLists.txt new file mode 100644 index 000000000000..4ef870b61124 --- /dev/null +++ b/mlir/tools/mlir-src-sharder/CMakeLists.txt @@ -0,0 +1,14 @@ +set(LLVM_LINK_COMPONENTS Support) +set(LIBS MLIRSupport) + +add_tablegen(mlir-src-sharder MLIR_SRC_SHARDER + mlir-src-sharder.cpp + + DEPENDS + ${LIBS} + ) + +set_target_properties(mlir-src-sharder PROPERTIES FOLDER "Tablegenning") +target_link_libraries(mlir-src-sharder PRIVATE ${LIBS}) + +mlir_check_all_link_libraries(mlir-src-sharder) diff --git a/mlir/tools/mlir-src-sharder/mlir-src-sharder.cpp b/mlir/tools/mlir-src-sharder/mlir-src-sharder.cpp new file mode 100644 index 000000000000..dc1e2939c7d2 --- /dev/null +++ b/mlir/tools/mlir-src-sharder/mlir-src-sharder.cpp @@ -0,0 +1,114 @@ +//===- mlir-src-sharder.cpp - A tool for sharder generated source files ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "mlir/Support/FileUtilities.h" +#include "mlir/Support/LogicalResult.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/ToolOutputFile.h" + +using namespace mlir; + +/// Create a dependency file for `-d` option. +/// +/// This functionality is generally only for the benefit of the build system, +/// and is modeled after the same option in TableGen. +static LogicalResult createDependencyFile(StringRef outputFilename, + StringRef dependencyFile) { + if (outputFilename == "-") { + llvm::errs() << "error: the option -d must be used together with -o\n"; + return failure(); + } + + std::string errorMessage; + std::unique_ptr outputFile = + openOutputFile(dependencyFile, &errorMessage); + if (!outputFile) { + llvm::errs() << errorMessage << "\n"; + return failure(); + } + + outputFile->os() << outputFilename << ":\n"; + outputFile->keep(); + return success(); +} + +int main(int argc, char **argv) { + // FIXME: This is necessary because we link in TableGen, which defines its + // options as static variables.. some of which overlap with our options. + llvm::cl::ResetCommandLineParser(); + + llvm::cl::opt opShardIndex( + "op-shard-index", llvm::cl::desc("The current shard index")); + llvm::cl::opt inputFilename(llvm::cl::Positional, + llvm::cl::desc(""), + llvm::cl::init("-")); + llvm::cl::opt outputFilename( + "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"), + llvm::cl::init("-")); + llvm::cl::list includeDirs( + "I", llvm::cl::desc("Directory of include files"), + llvm::cl::value_desc("directory"), llvm::cl::Prefix); + llvm::cl::opt dependencyFilename( + "d", llvm::cl::desc("Dependency filename"), + llvm::cl::value_desc("filename"), llvm::cl::init("")); + llvm::cl::opt writeIfChanged( + "write-if-changed", + llvm::cl::desc("Only write to the output file if it changed")); + + llvm::InitLLVM y(argc, argv); + llvm::cl::ParseCommandLineOptions(argc, argv); + + // Open the input file. + std::string errorMessage; + std::unique_ptr inputFile = + openInputFile(inputFilename, &errorMessage); + if (!inputFile) { + llvm::errs() << errorMessage << "\n"; + return 1; + } + + // Write the output to a buffer. + std::string outputStr; + llvm::raw_string_ostream os(outputStr); + os << "#define GET_OP_DEFS_" << opShardIndex << "\n" + << inputFile->getBuffer(); + + // Determine whether we need to write the output file. + bool shouldWriteOutput = true; + if (writeIfChanged) { + // Only update the real output file if there are any differences. This + // prevents recompilation of all the files depending on it if there aren't + // any. + if (auto existingOrErr = + llvm::MemoryBuffer::getFile(outputFilename, /*IsText=*/true)) + if (std::move(existingOrErr.get())->getBuffer() == os.str()) + shouldWriteOutput = false; + } + + // Populate the output file if necessary. + if (shouldWriteOutput) { + std::unique_ptr outputFile = + openOutputFile(outputFilename, &errorMessage); + if (!outputFile) { + llvm::errs() << errorMessage << "\n"; + return 1; + } + outputFile->os() << os.str(); + outputFile->keep(); + } + + // Always write the depfile, even if the main output hasn't changed. If it's + // missing, Ninja considers the output dirty. + if (!dependencyFilename.empty()) + if (failed(createDependencyFile(outputFilename, dependencyFilename))) + return 1; + + return 0; +} diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp index 53ed5cb7c043..63fe5a809907 100644 --- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -4303,32 +4303,15 @@ void OpOperandAdaptorEmitter::emitDef( emitter.adaptor.writeDefTo(os); } -// Emits the opcode enum and op classes. -static void emitOpClasses(const RecordKeeper &recordKeeper, - const std::vector &defs, raw_ostream &os, - bool emitDecl) { - // First emit forward declaration for each class, this allows them to refer - // to each others in traits for example. - if (emitDecl) { - os << "#if defined(GET_OP_CLASSES) || defined(GET_OP_FWD_DEFINES)\n"; - os << "#undef GET_OP_FWD_DEFINES\n"; - for (auto *def : defs) { - Operator op(*def); - NamespaceEmitter emitter(os, op.getCppNamespace()); - os << "class " << op.getCppClassName() << ";\n"; - } - os << "#endif\n\n"; - } - - IfDefScope scope("GET_OP_CLASSES", os); +/// Emit the class declarations or definitions for the given op defs. +static void +emitOpClasses(const RecordKeeper &recordKeeper, + const std::vector &defs, raw_ostream &os, + const StaticVerifierFunctionEmitter &staticVerifierEmitter, + bool emitDecl) { if (defs.empty()) return; - // Generate all of the locally instantiated methods first. - StaticVerifierFunctionEmitter staticVerifierEmitter(os, recordKeeper); - os << formatv(opCommentHeader, "Local Utility Method", "Definitions"); - staticVerifierEmitter.emitOpConstraints(defs, emitDecl); - for (auto *def : defs) { Operator op(*def); if (emitDecl) { @@ -4358,34 +4341,145 @@ static void emitOpClasses(const RecordKeeper &recordKeeper, } } -// Emits a comma-separated list of the ops. -static void emitOpList(const std::vector &defs, raw_ostream &os) { - IfDefScope scope("GET_OP_LIST", os); +/// Emit the declarations for the provided op classes. +static void emitOpClassDecls(const RecordKeeper &recordKeeper, + const std::vector &defs, + raw_ostream &os) { + // First emit forward declaration for each class, this allows them to refer + // to each others in traits for example. + for (auto *def : defs) { + Operator op(*def); + NamespaceEmitter emitter(os, op.getCppNamespace()); + os << "class " << op.getCppClassName() << ";\n"; + } + + // Emit the op class declarations. + IfDefScope scope("GET_OP_CLASSES", os); + if (defs.empty()) + return; + StaticVerifierFunctionEmitter staticVerifierEmitter(os, recordKeeper); + staticVerifierEmitter.collectOpConstraints(defs); + emitOpClasses(recordKeeper, defs, os, staticVerifierEmitter, + /*emitDecl=*/true); +} + +/// Emit the definitions for the provided op classes. +static void emitOpClassDefs(const RecordKeeper &recordKeeper, + ArrayRef defs, raw_ostream &os, + StringRef constraintPrefix = "") { + if (defs.empty()) + return; + + // Generate all of the locally instantiated methods first. + StaticVerifierFunctionEmitter staticVerifierEmitter(os, recordKeeper, + constraintPrefix); + os << formatv(opCommentHeader, "Local Utility Method", "Definitions"); + staticVerifierEmitter.collectOpConstraints(defs); + staticVerifierEmitter.emitOpConstraints(defs); - interleave( - // TODO: We are constructing the Operator wrapper instance just for - // getting it's qualified class name here. Reduce the overhead by having a - // lightweight version of Operator class just for that purpose. - defs, [&os](Record *def) { os << Operator(def).getQualCppClassName(); }, - [&os]() { os << ",\n"; }); + // Emit the classes. + emitOpClasses(recordKeeper, defs, os, staticVerifierEmitter, + /*emitDecl=*/false); } +/// Emit op declarations for all op records. static bool emitOpDecls(const RecordKeeper &recordKeeper, raw_ostream &os) { emitSourceFileHeader("Op Declarations", os, recordKeeper); std::vector defs = getRequestedOpDefinitions(recordKeeper); - emitOpClasses(recordKeeper, defs, os, /*emitDecl=*/true); + emitOpClassDecls(recordKeeper, defs, os); + + // If we are generating sharded op definitions, emit the sharded op + // registration hooks. + SmallVector, 4> shardedDefs; + shardOpDefinitions(defs, shardedDefs); + if (defs.empty() || shardedDefs.size() <= 1) + return false; + + Dialect dialect = Operator(defs.front()).getDialect(); + NamespaceEmitter ns(os, dialect); + + const char *const opRegistrationHook = + "void register{0}Operations{1}({2}::{0} *dialect);\n"; + os << formatv(opRegistrationHook, dialect.getCppClassName(), "", + dialect.getCppNamespace()); + for (unsigned i = 0; i < shardedDefs.size(); ++i) { + os << formatv(opRegistrationHook, dialect.getCppClassName(), i, + dialect.getCppNamespace()); + } return false; } +/// Generate the dialect op registration hook and the op class definitions for a +/// shard of ops. +static void emitOpDefShard(const RecordKeeper &recordKeeper, + ArrayRef defs, const Dialect &dialect, + unsigned shardIndex, unsigned shardCount, + raw_ostream &os) { + std::string shardGuard = "GET_OP_DEFS_"; + std::string indexStr = std::to_string(shardIndex); + shardGuard += indexStr; + IfDefScope scope(shardGuard, os); + + // Emit the op registration hook in the first shard. + const char *const opRegistrationHook = + "void {0}::register{1}Operations{2}({0}::{1} *dialect) {{\n"; + if (shardIndex == 0) { + os << formatv(opRegistrationHook, dialect.getCppNamespace(), + dialect.getCppClassName(), ""); + for (unsigned i = 0; i < shardCount; ++i) { + os << formatv(" {0}::register{1}Operations{2}(dialect);\n", + dialect.getCppNamespace(), dialect.getCppClassName(), i); + } + os << "}\n"; + } + + // Generate the per-shard op registration hook. + os << formatv(opCommentHeader, dialect.getCppClassName(), + "Op Registration Hook") + << formatv(opRegistrationHook, dialect.getCppNamespace(), + dialect.getCppClassName(), shardIndex); + for (Record *def : defs) { + os << formatv(" ::mlir::RegisteredOperationName::insert<{0}>(*dialect);\n", + Operator(def).getQualCppClassName()); + } + os << "}\n"; + + // Generate the per-shard op definitions. + emitOpClassDefs(recordKeeper, defs, os, indexStr); +} + +/// Emit op definitions for all op records. static bool emitOpDefs(const RecordKeeper &recordKeeper, raw_ostream &os) { emitSourceFileHeader("Op Definitions", os, recordKeeper); std::vector defs = getRequestedOpDefinitions(recordKeeper); - emitOpList(defs, os); - emitOpClasses(recordKeeper, defs, os, /*emitDecl=*/false); + SmallVector, 4> shardedDefs; + shardOpDefinitions(defs, shardedDefs); + + // If no shard was requested, emit the regular op list and class definitions. + if (shardedDefs.size() == 1) { + { + IfDefScope scope("GET_OP_LIST", os); + interleave( + defs, os, + [&](Record *def) { os << Operator(def).getQualCppClassName(); }, + ",\n"); + } + { + IfDefScope scope("GET_OP_CLASSES", os); + emitOpClassDefs(recordKeeper, defs, os); + } + return false; + } + if (defs.empty()) + return false; + Dialect dialect = Operator(defs.front()).getDialect(); + for (auto [idx, value] : llvm::enumerate(shardedDefs)) { + emitOpDefShard(recordKeeper, value, dialect, idx, shardedDefs.size(), os); + } return false; } diff --git a/mlir/tools/mlir-tblgen/OpGenHelpers.cpp b/mlir/tools/mlir-tblgen/OpGenHelpers.cpp index 7fd34df8460d..c2a2423a2402 100644 --- a/mlir/tools/mlir-tblgen/OpGenHelpers.cpp +++ b/mlir/tools/mlir-tblgen/OpGenHelpers.cpp @@ -31,6 +31,10 @@ static cl::opt opExcFilter( "op-exclude-regex", cl::desc("Regex of name of op's to exclude (no filter if empty)"), cl::cat(opDefGenCat)); +static cl::opt opShardCount( + "op-shard-count", + cl::desc("The number of shards into which the op classes will be divided"), + cl::cat(opDefGenCat), cl::init(1)); static std::string getOperationName(const Record &def) { auto prefix = def.getValueAsDef("opDialect")->getValueAsString("name"); @@ -79,4 +83,23 @@ bool mlir::tblgen::isPythonReserved(StringRef str) { reserved.insert("issubclass"); reserved.insert("type"); return reserved.contains(str); -} \ No newline at end of file +} + +void mlir::tblgen::shardOpDefinitions( + ArrayRef defs, + SmallVectorImpl> &shardedDefs) { + assert(opShardCount > 0 && "expected a positive shard count"); + if (opShardCount == 1) { + shardedDefs.push_back(defs); + return; + } + + unsigned minShardSize = defs.size() / opShardCount; + unsigned numMissing = defs.size() - minShardSize * opShardCount; + shardedDefs.reserve(opShardCount); + for (unsigned i = 0, start = 0; i < opShardCount; ++i) { + unsigned size = minShardSize + (i < numMissing); + shardedDefs.push_back(defs.slice(start, size)); + start += size; + } +} diff --git a/mlir/tools/mlir-tblgen/OpGenHelpers.h b/mlir/tools/mlir-tblgen/OpGenHelpers.h index 3dcff14d1221..1b43d5d3ce3a 100644 --- a/mlir/tools/mlir-tblgen/OpGenHelpers.h +++ b/mlir/tools/mlir-tblgen/OpGenHelpers.h @@ -13,6 +13,7 @@ #ifndef MLIR_TOOLS_MLIRTBLGEN_OPGENHELPERS_H_ #define MLIR_TOOLS_MLIRTBLGEN_OPGENHELPERS_H_ +#include "mlir/Support/LLVM.h" #include "llvm/TableGen/Record.h" #include @@ -28,6 +29,10 @@ getRequestedOpDefinitions(const llvm::RecordKeeper &recordKeeper); /// Regenerate using python -c"print(set(sorted(__import__('keyword').kwlist)))" bool isPythonReserved(llvm::StringRef str); +/// Shard the op defintions into the number of shards set by "op-shard-count". +void shardOpDefinitions(ArrayRef defs, + SmallVectorImpl> &shardedDefs); + } // namespace tblgen } // namespace mlir diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index 05f096163fdd..3eb0f67bbd88 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -9771,6 +9771,15 @@ cc_binary( ], ) +cc_binary( + name = "mlir-src-sharder", + srcs = ["tools/mlir-src-sharder/mlir-src-sharder.cpp"], + deps = [ + ":Support", + "//llvm:Support", + ], +) + cc_binary( name = "mlir-linalg-ods-yaml-gen", srcs = [ diff --git a/utils/bazel/llvm-project-overlay/mlir/tblgen.bzl b/utils/bazel/llvm-project-overlay/mlir/tblgen.bzl index fdf6a57107ac..e45ba1fe0ef7 100644 --- a/utils/bazel/llvm-project-overlay/mlir/tblgen.bzl +++ b/utils/bazel/llvm-project-overlay/mlir/tblgen.bzl @@ -432,3 +432,136 @@ def gentbl_cc_library( copts = copts, **kwargs ) + +def _gentbl_shard_impl(ctx): + args = ctx.actions.args() + args.add(ctx.file.src_file) + args.add("-op-shard-index", ctx.attr.index) + args.add("-o", ctx.outputs.out.path) + ctx.actions.run( + outputs = [ctx.outputs.out], + inputs = [ctx.file.src_file], + executable = ctx.executable.sharder, + arguments = [args], + use_default_shell_env = True, + mnemonic = "ShardGenerate", + ) + +gentbl_shard_rule = rule( + _gentbl_shard_impl, + doc = "", + output_to_genfiles = True, + attrs = { + "index": attr.int(mandatory = True, doc = ""), + "sharder": attr.label( + doc = "", + executable = True, + cfg = "exec", + ), + "src_file": attr.label( + doc = "", + allow_single_file = True, + mandatory = True, + ), + "out": attr.output( + doc = "", + mandatory = True, + ), + }, +) + +def gentbl_sharded_ops( + name, + tblgen, + sharder, + td_file, + shard_count, + src_file, + src_out, + hdr_out, + test = False, + includes = [], + strip_include_prefix = None, + deps = []): + """Generate sharded op declarations and definitions. + + This special build rule shards op definitions in a TableGen file and generates multiple copies + of a template source file for including and compiling each shard. The rule defines a filegroup + consisting of the source shards, the generated source file, and the generated header file. + + Args: + name: The name of the filegroup. + tblgen: The binary used to produce the output. + sharder: The source file sharder to use. + td_file: The primary table definitions file. + shard_count: The number of op definition shards to produce. + src_file: The source file template. + src_out: The generated source file. + hdr_out: The generated header file. + test: Whether this is a test target. + includes: See gentbl_rule.includes + deps: See gentbl_rule.deps + strip_include_prefix: Attribute to pass through to cc_library. + """ + cc_lib_name = name + "__gentbl_cc_lib" + gentbl_cc_library( + name = cc_lib_name, + strip_include_prefix = strip_include_prefix, + includes = includes, + tbl_outs = [ + ( + [ + "-gen-op-defs", + "-op-shard-count=" + str(shard_count), + ], + src_out, + ), + ( + [ + "-gen-op-decls", + "-op-shard-count=" + str(shard_count), + ], + hdr_out, + ), + ], + tblgen = tblgen, + td_file = td_file, + test = test, + deps = deps, + ) + all_files = [hdr_out, src_out] + for i in range(0, shard_count): + out_file = "shard_copy_" + str(i) + "_" + src_file + gentbl_shard_rule( + index = i, + name = name + "__src_shard" + str(i), + testonly = test, + out = out_file, + sharder = sharder, + src_file = src_file, + ) + all_files.append(out_file) + native.filegroup(name = name, srcs = all_files) + +def gentbl_sharded_op_defs(name, source_file, shard_count): + """Generates multiple copies of a source file that includes sharded op definitions. + + Args: + name: The name of the rule. + source_file: The source to copy. + shard_count: The number of shards. + + Returns: + A list of the copied filenames to be included in the dialect library. + """ + copies = [] + for i in range(0, shard_count): + out_file = "shard_copy_" + str(i) + "_" + source_file + copies.append(out_file) + native.genrule( + name = name + "_shard_" + str(i), + srcs = [source_file], + outs = [out_file], + cmd = "echo -e \"#define GET_OP_DEFS_" + str(i) + "\n$$(cat $(SRCS))\" > $(OUTS)", + ) + return copies -- GitLab From ae22ac95354629baca45d979038d73a4ce40d081 Mon Sep 17 00:00:00 2001 From: Jeff Niu Date: Wed, 24 Apr 2024 14:59:00 -0700 Subject: [PATCH 027/733] [mlir][test] Shard the Test Dialect (NFC) (#89628) This PR uses the new op sharding mechanism in tablegen to shard the test dialect's op definitions. This breaks the definition of ops into multiple source files, speeding up compile time of the test dialect dramatically. This improves developer cycle times when iterating on the test dialect. --- mlir/test/lib/Dialect/Test/CMakeLists.txt | 6 +++-- mlir/test/lib/Dialect/Test/TestDialect.cpp | 5 +--- mlir/test/lib/Dialect/Test/TestOps.cpp | 1 - .../mlir/test/BUILD.bazel | 25 +++++++++++-------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/mlir/test/lib/Dialect/Test/CMakeLists.txt b/mlir/test/lib/Dialect/Test/CMakeLists.txt index f63e4d330e6a..fab893780933 100644 --- a/mlir/test/lib/Dialect/Test/CMakeLists.txt +++ b/mlir/test/lib/Dialect/Test/CMakeLists.txt @@ -31,8 +31,6 @@ mlir_tablegen(TestOpEnums.cpp.inc -gen-enum-defs) add_public_tablegen_target(MLIRTestEnumDefIncGen) set(LLVM_TARGET_DEFINITIONS TestOps.td) -mlir_tablegen(TestOps.h.inc -gen-op-decls) -mlir_tablegen(TestOps.cpp.inc -gen-op-defs) mlir_tablegen(TestOpsDialect.h.inc -gen-dialect-decls -dialect=test) mlir_tablegen(TestOpsDialect.cpp.inc -gen-dialect-defs -dialect=test) mlir_tablegen(TestPatterns.inc -gen-rewriters) @@ -43,6 +41,8 @@ mlir_tablegen(TestOpsSyntax.h.inc -gen-op-decls) mlir_tablegen(TestOpsSyntax.cpp.inc -gen-op-defs) add_public_tablegen_target(MLIRTestOpsSyntaxIncGen) +add_sharded_ops(TestOps 20) + # Exclude tests from libMLIR.so add_mlir_library(MLIRTestDialect TestAttributes.cpp @@ -56,6 +56,7 @@ add_mlir_library(MLIRTestDialect TestTypes.cpp TestOpsSyntax.cpp TestDialectInterfaces.cpp + ${SHARDED_SRCS} EXCLUDE_FROM_LIBMLIR @@ -66,6 +67,7 @@ add_mlir_library(MLIRTestDialect MLIRTestTypeDefIncGen MLIRTestOpsIncGen MLIRTestOpsSyntaxIncGen + MLIRTestOpsShardGen LINK_LIBS PUBLIC MLIRControlFlowInterfaces diff --git a/mlir/test/lib/Dialect/Test/TestDialect.cpp b/mlir/test/lib/Dialect/Test/TestDialect.cpp index 77fd7e61bd3a..bfb9592e6382 100644 --- a/mlir/test/lib/Dialect/Test/TestDialect.cpp +++ b/mlir/test/lib/Dialect/Test/TestDialect.cpp @@ -326,12 +326,9 @@ struct TestOpEffectInterfaceFallback void TestDialect::initialize() { registerAttributes(); registerTypes(); - addOperations< -#define GET_OP_LIST -#include "TestOps.cpp.inc" - >(); registerOpsSyntax(); addOperations(); + registerTestDialectOperations(this); registerDynamicOp(getDynamicGenericOp(this)); registerDynamicOp(getDynamicOneOperandTwoResultsOp(this)); registerDynamicOp(getDynamicCustomParserPrinterOp(this)); diff --git a/mlir/test/lib/Dialect/Test/TestOps.cpp b/mlir/test/lib/Dialect/Test/TestOps.cpp index ce7e476be74e..47d5b1b19121 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.cpp +++ b/mlir/test/lib/Dialect/Test/TestOps.cpp @@ -14,5 +14,4 @@ using namespace mlir; using namespace test; -#define GET_OP_CLASSES #include "TestOps.cpp.inc" diff --git a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel index dc5f4047c286..b98f7eb5613a 100644 --- a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel @@ -4,7 +4,7 @@ load("@bazel_skylib//rules:expand_template.bzl", "expand_template") load("//llvm:lit_test.bzl", "package_path") -load("//mlir:tblgen.bzl", "gentbl_cc_library", "td_library") +load("//mlir:tblgen.bzl", "gentbl_cc_library", "td_library", "gentbl_sharded_ops", "td_library") package( default_visibility = ["//visibility:public"], @@ -151,14 +151,6 @@ gentbl_cc_library( name = "TestOpsIncGen", strip_include_prefix = "lib/Dialect/Test", tbl_outs = [ - ( - ["-gen-op-decls"], - "lib/Dialect/Test/TestOps.h.inc", - ), - ( - ["-gen-op-defs"], - "lib/Dialect/Test/TestOps.cpp.inc", - ), ( [ "-gen-dialect-decls", @@ -370,12 +362,25 @@ cc_library( ], ) +gentbl_sharded_ops( + name = "TestDialectOpSrcs", + hdr_out = "lib/Dialect/Test/TestOps.h.inc", + shard_count = 20, + sharder = "//mlir:mlir-src-sharder", + src_file = "lib/Dialect/Test/TestOps.cpp", + src_out = "lib/Dialect/Test/TestOps.cpp.inc", + tblgen = "//mlir:mlir-tblgen", + td_file = "lib/Dialect/Test/TestOps.td", + test = True, + deps = [":TestOpTdFiles"], +) + cc_library( name = "TestDialect", srcs = glob( ["lib/Dialect/Test/*.cpp"], exclude = ["lib/Dialect/Test/TestToLLVMIRTranslation.cpp"], - ), + ) + [":TestDialectOpSrcs"], hdrs = glob(["lib/Dialect/Test/*.h"]), includes = [ "lib/Dialect/Test", -- GitLab From 83d06162cca4f35a68e9c64032ba348ac3e27647 Mon Sep 17 00:00:00 2001 From: Jeff Niu Date: Wed, 24 Apr 2024 14:59:14 -0700 Subject: [PATCH 028/733] [mlir][ods] Add documentation on how to use sharded op definitions (NFC) (#89664) This adds explanations and instructions on how to set up a dialect for sharded op definitions to the MLIR documentation. --- mlir/docs/DefiningDialects/Operations.md | 94 ++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/mlir/docs/DefiningDialects/Operations.md b/mlir/docs/DefiningDialects/Operations.md index 729393d53626..79a0cc55f138 100644 --- a/mlir/docs/DefiningDialects/Operations.md +++ b/mlir/docs/DefiningDialects/Operations.md @@ -1114,6 +1114,100 @@ void process(AddOp op, ArrayRef newOperands) { } ``` +#### Sharded Operation Definitions + +Large dialects with many operations may struggle with C++ compile time of +generated op definitions, due to large compilation units. `mlir-tblgen` +provides the ability to shard op definitions by splitting them up evenly +by passing `-op-shard-count` to `-gen-op-defs` and `-gen-op-decls`. The tool +will generate a single include file for the definitions broken up by +`GET_OP_DEFS_${N}` where `${N}` is the shard number. A shard can be compiled in +a single compilation unit by adding a file like this to your dialect library: + +```c++ +#include "mlir/IR/Operation.h" +// Add any other required includes. + +// Utilities shared by generated op definitions: custom directive parsers, +// printers, etc. +#include "OpUtils.h" + +#define GET_OP_DEFS_0 +#include "MyDialectOps.cpp.inc" +``` + +Note: this requires restructing shared utility functions within the dialect +library so they can be shared by multiple compilation units. I.e. instead of +defining `static` methods in the same source file, you should declare them in a +shared header and define them in their own source file. + +The op registration hooks are also sharded, because the template instantiation +can take a very long time to compile. Operations should be registered in your +dialect like: + +```c++ +void MyDialect::initialize() { + registerMyDialectOperations(this); +} +``` + +CMake and Bazel functions are included to make sharding dialects easier. +Assuming you have organized your operation utility functions into their own +header, define a file that looks like the one above, but without the `#define`: + +```c++ +// MyDialectOps.cpp +#include "mlir/IR/Operation.h" + +#include "OpUtils.h" + +#include "MyDialectOps.cpp.inc" +``` + +In CMake, remove the manual `mlir_tablegen` invocations and replace them with: + +```cmake +set(LLVM_TARGET_DEFINITIONS MyDialectOps.td) +add_sharded_ops(MyDialectOps 8) # shard the op definitions by 8 + +add_mlir_library(MyDialect + MyDialect.cpp + MyDialectOpDefs.cpp + ${SHARDED_SRCS} + + DEPENDS + MLIRTestOpsShardGen +) +``` + +This will automatically duplicate the `MyDialectOps.cpp` source file and add the +`#define` up the number of shards indicated. + +It is recommended that any out-of-line op member functions (like verifiers) be +defined in a separate source file. In this example, it is called +`MyDialectOpDefs.cpp`. + +In Bazel, remove the `-gen-op-defs` and `-gen-op-decls` invocations, and add + +```bazel +gentbl_sharded_ops( + name = "MyDialectOpSrcs", + hdr_out = "MyDialectOps.h.inc", + shard_count = 8, + sharder = "//mlir:mlir-src-sharder", + src_file = "MyDialectOps.cpp", + src_out = "MyDialectOps.cpp.inc", + tblgen = "//mlir:mlir-tblgen", + td_file = "MyDialectOps.td", + deps = [":MyDialectOpsTdFiles"], +) + +cc_library( + name = "MyDialect", + srcs = glob(["MyDialect/*.cpp"]) + [":MyDialectOpSrcs"] +) +``` + ## Constraints Constraint is a core concept in table-driven operation definition: operation -- GitLab From 0e1bb1d8352ce21808523357d315b73da0d53560 Mon Sep 17 00:00:00 2001 From: Peter Klausler <35819229+klausler@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:08:22 -0700 Subject: [PATCH 029/733] [flang] Don't convert actual arguments when interface is implicit (#89795) When the interface of a procedure is implicit at the point of call, don't perform actual argument type conversion to the types of the dummy arguments. This was inadvertently taking place in a case where the procedure has an implicit interface but was also defined in the same source file, so that its characteristics were known. --- flang/lib/Semantics/check-call.cpp | 6 ++++-- flang/lib/Semantics/expression.cpp | 4 ++-- flang/test/Semantics/arg-convert.f90 | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 flang/test/Semantics/arg-convert.f90 diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp index ce82cccf26d5..db0949e905a6 100644 --- a/flang/lib/Semantics/check-call.cpp +++ b/flang/lib/Semantics/check-call.cpp @@ -1929,6 +1929,7 @@ bool CheckArguments(const characteristics::Procedure &proc, bool explicitInterface{proc.HasExplicitInterface()}; evaluate::FoldingContext foldingContext{context.foldingContext()}; parser::ContextualMessages &messages{foldingContext.messages()}; + bool allowArgumentConversions{true}; if (!explicitInterface || treatingExternalAsImplicit) { parser::Messages buffer; { @@ -1945,11 +1946,12 @@ bool CheckArguments(const characteristics::Procedure &proc, } return false; // don't pile on } + allowArgumentConversions = false; } if (explicitInterface) { auto buffer{CheckExplicitInterface(proc, actuals, context, &scope, - intrinsic, /*allowArgumentConversions=*/true, /*extentErrors=*/true, - ignoreImplicitVsExplicit)}; + intrinsic, allowArgumentConversions, + /*extentErrors=*/true, ignoreImplicitVsExplicit)}; if (!buffer.empty()) { if (treatingExternalAsImplicit) { if (auto *msg{messages.Say( diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index a270e4b385e8..b8396209fc68 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -2989,8 +2989,8 @@ void ExpressionAnalyzer::Analyze(const parser::CallStmt &callStmt) { for (const auto &arg : actualArgList) { analyzer.Analyze(arg, true /* is subroutine call */); } - auto chevrons{AnalyzeChevrons(callStmt)}; - if (!analyzer.fatalErrors() && chevrons) { + if (auto chevrons{AnalyzeChevrons(callStmt)}; + chevrons && !analyzer.fatalErrors()) { if (std::optional callee{ GetCalleeAndArguments(std::get(call.t), analyzer.GetActuals(), true /* subroutine */)}) { diff --git a/flang/test/Semantics/arg-convert.f90 b/flang/test/Semantics/arg-convert.f90 new file mode 100644 index 000000000000..7951bedf49d0 --- /dev/null +++ b/flang/test/Semantics/arg-convert.f90 @@ -0,0 +1,16 @@ +!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +!Ensure that argument conversion does not take place when the procedure +!interface is implicit at the point of call, even when the interface +!is known due because the procedure's definition is in the same source file. + +subroutine test +!CHECK: warning: If the procedure's interface were explicit, this reference would be in error +!CHECK: because: Actual argument type 'INTEGER(8)' is not compatible with dummy argument type 'INTEGER(4)' +!CHECK: CALL samesourcefile((1_8)) + call sameSourceFile((1_8)) +!CHECK: CALL somewhereelse((2_8)) + call somewhereElse((2_8)) +end + +subroutine sameSourceFile(n) +end -- GitLab From 68a27989d0c8d58a64dcbb1c78b7002c68a723b2 Mon Sep 17 00:00:00 2001 From: Peter Klausler <35819229+klausler@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:25:19 -0700 Subject: [PATCH 030/733] =?UTF-8?q?[flang]=20Accept=20and=20ignore=20compi?= =?UTF-8?q?ler=20directives=20between=20internal=20subpro=E2=80=A6=20(#898?= =?UTF-8?q?10)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …grams The parser only recognizes compiler directives that appear within internal / module subprograms, not those that might appear between them. Extend to allow them between subprograms as well. --- flang/include/flang/Parser/parse-tree.h | 3 +- flang/lib/Parser/Fortran-parsers.cpp | 3 +- flang/lib/Semantics/program-tree.cpp | 86 +++++++++++++++++-------- flang/lib/Semantics/program-tree.h | 30 ++++++--- flang/lib/Semantics/resolve-names.cpp | 4 +- flang/test/Parser/unrecognized-dir.f90 | 8 ++- 6 files changed, 91 insertions(+), 43 deletions(-) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index d7c23755c57b..4641f9d20d5b 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -455,7 +455,8 @@ struct SpecificationPart { struct InternalSubprogram { UNION_CLASS_BOILERPLATE(InternalSubprogram); std::variant, - common::Indirection> + common::Indirection, + common::Indirection> u; }; diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp index 2bdb8e38db95..ff01974b549a 100644 --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -123,7 +123,8 @@ TYPE_PARSER(first( TYPE_CONTEXT_PARSER("internal subprogram"_en_US, (construct(indirect(functionSubprogram)) || construct(indirect(subroutineSubprogram))) / - forceEndOfStmt) + forceEndOfStmt || + construct(indirect(compilerDirective))) // R511 internal-subprogram-part -> contains-stmt [internal-subprogram]... TYPE_CONTEXT_PARSER("internal subprogram part"_en_US, diff --git a/flang/lib/Semantics/program-tree.cpp b/flang/lib/Semantics/program-tree.cpp index bf773f3810c8..13c85c17459e 100644 --- a/flang/lib/Semantics/program-tree.cpp +++ b/flang/lib/Semantics/program-tree.cpp @@ -10,6 +10,7 @@ #include "flang/Common/idioms.h" #include "flang/Parser/char-block.h" #include "flang/Semantics/scope.h" +#include "flang/Semantics/semantics.h" namespace Fortran::semantics { @@ -76,7 +77,8 @@ static void GetGenerics( } template -static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) { +static ProgramTree BuildSubprogramTree( + const parser::Name &name, SemanticsContext &context, const T &x) { const auto &spec{std::get(x.t)}; const auto &exec{std::get(x.t)}; const auto &subps{ @@ -89,7 +91,11 @@ static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) { for (const auto &subp : std::get>(subps->t)) { common::visit( - [&](const auto &y) { node.AddChild(ProgramTree::Build(y.value())); }, + [&](const auto &y) { + if (auto child{ProgramTree::Build(y.value(), context)}) { + node.AddChild(std::move(*child)); + } + }, subp.u); } } @@ -97,13 +103,14 @@ static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) { } static ProgramTree BuildSubprogramTree( - const parser::Name &name, const parser::BlockData &x) { + const parser::Name &name, SemanticsContext &, const parser::BlockData &x) { const auto &spec{std::get(x.t)}; return ProgramTree{name, spec}; } template -static ProgramTree BuildModuleTree(const parser::Name &name, const T &x) { +static ProgramTree BuildModuleTree( + const parser::Name &name, SemanticsContext &context, const T &x) { const auto &spec{std::get(x.t)}; const auto &subps{std::get>(x.t)}; ProgramTree node{name, spec}; @@ -112,28 +119,42 @@ static ProgramTree BuildModuleTree(const parser::Name &name, const T &x) { for (const auto &subp : std::get>(subps->t)) { common::visit( - [&](const auto &y) { node.AddChild(ProgramTree::Build(y.value())); }, + [&](const auto &y) { + if (auto child{ProgramTree::Build(y.value(), context)}) { + node.AddChild(std::move(*child)); + } + }, subp.u); } } return node; } -ProgramTree ProgramTree::Build(const parser::ProgramUnit &x) { - return common::visit([](const auto &y) { return Build(y.value()); }, x.u); +ProgramTree ProgramTree::Build( + const parser::ProgramUnit &x, SemanticsContext &context) { + return common::visit( + [&](const auto &y) { + auto node{Build(y.value(), context)}; + CHECK(node.has_value()); + return std::move(*node); + }, + x.u); } -ProgramTree ProgramTree::Build(const parser::MainProgram &x) { +std::optional ProgramTree::Build( + const parser::MainProgram &x, SemanticsContext &context) { const auto &stmt{ std::get>>(x.t)}; const auto &end{std::get>(x.t)}; static parser::Name emptyName; - auto result{stmt ? BuildSubprogramTree(stmt->statement.v, x).set_stmt(*stmt) - : BuildSubprogramTree(emptyName, x)}; - return result.set_endStmt(end); + auto result{stmt + ? BuildSubprogramTree(stmt->statement.v, context, x).set_stmt(*stmt) + : BuildSubprogramTree(emptyName, context, x)}; + return std::move(result.set_endStmt(end)); } -ProgramTree ProgramTree::Build(const parser::FunctionSubprogram &x) { +std::optional ProgramTree::Build( + const parser::FunctionSubprogram &x, SemanticsContext &context) { const auto &stmt{std::get>(x.t)}; const auto &end{std::get>(x.t)}; const auto &name{std::get(stmt.statement.t)}; @@ -144,13 +165,14 @@ ProgramTree ProgramTree::Build(const parser::FunctionSubprogram &x) { bindingSpec = &*suffix->binding; } } - return BuildSubprogramTree(name, x) + return BuildSubprogramTree(name, context, x) .set_stmt(stmt) .set_endStmt(end) .set_bindingSpec(bindingSpec); } -ProgramTree ProgramTree::Build(const parser::SubroutineSubprogram &x) { +std::optional ProgramTree::Build( + const parser::SubroutineSubprogram &x, SemanticsContext &context) { const auto &stmt{std::get>(x.t)}; const auto &end{std::get>(x.t)}; const auto &name{std::get(stmt.statement.t)}; @@ -159,48 +181,56 @@ ProgramTree ProgramTree::Build(const parser::SubroutineSubprogram &x) { stmt.statement.t)}) { bindingSpec = &*binding; } - return BuildSubprogramTree(name, x) + return BuildSubprogramTree(name, context, x) .set_stmt(stmt) .set_endStmt(end) .set_bindingSpec(bindingSpec); } -ProgramTree ProgramTree::Build(const parser::SeparateModuleSubprogram &x) { +std::optional ProgramTree::Build( + const parser::SeparateModuleSubprogram &x, SemanticsContext &context) { const auto &stmt{std::get>(x.t)}; const auto &end{ std::get>(x.t)}; const auto &name{stmt.statement.v}; - return BuildSubprogramTree(name, x).set_stmt(stmt).set_endStmt(end); + return BuildSubprogramTree(name, context, x).set_stmt(stmt).set_endStmt(end); } -ProgramTree ProgramTree::Build(const parser::Module &x) { +std::optional ProgramTree::Build( + const parser::Module &x, SemanticsContext &context) { const auto &stmt{std::get>(x.t)}; const auto &end{std::get>(x.t)}; const auto &name{stmt.statement.v}; - return BuildModuleTree(name, x).set_stmt(stmt).set_endStmt(end); + return BuildModuleTree(name, context, x).set_stmt(stmt).set_endStmt(end); } -ProgramTree ProgramTree::Build(const parser::Submodule &x) { +std::optional ProgramTree::Build( + const parser::Submodule &x, SemanticsContext &context) { const auto &stmt{std::get>(x.t)}; const auto &end{std::get>(x.t)}; const auto &name{std::get(stmt.statement.t)}; - return BuildModuleTree(name, x).set_stmt(stmt).set_endStmt(end); + return BuildModuleTree(name, context, x).set_stmt(stmt).set_endStmt(end); } -ProgramTree ProgramTree::Build(const parser::BlockData &x) { +std::optional ProgramTree::Build( + const parser::BlockData &x, SemanticsContext &context) { const auto &stmt{std::get>(x.t)}; const auto &end{std::get>(x.t)}; static parser::Name emptyName; - auto result{stmt.statement.v ? BuildSubprogramTree(*stmt.statement.v, x) - : BuildSubprogramTree(emptyName, x)}; - return result.set_stmt(stmt).set_endStmt(end); + auto result{stmt.statement.v + ? BuildSubprogramTree(*stmt.statement.v, context, x) + : BuildSubprogramTree(emptyName, context, x)}; + return std::move(result.set_stmt(stmt).set_endStmt(end)); } -ProgramTree ProgramTree::Build(const parser::CompilerDirective &) { - DIE("ProgramTree::Build() called for CompilerDirective"); +std::optional ProgramTree::Build( + const parser::CompilerDirective &x, SemanticsContext &context) { + context.Say(x.source, "Compiler directive ignored here"_warn_en_US); + return std::nullopt; } -ProgramTree ProgramTree::Build(const parser::OpenACCRoutineConstruct &) { +std::optional ProgramTree::Build( + const parser::OpenACCRoutineConstruct &, SemanticsContext &) { DIE("ProgramTree::Build() called for OpenACCRoutineConstruct"); } diff --git a/flang/lib/Semantics/program-tree.h b/flang/lib/Semantics/program-tree.h index d49b0405d8b1..ab00261a964a 100644 --- a/flang/lib/Semantics/program-tree.h +++ b/flang/lib/Semantics/program-tree.h @@ -26,6 +26,7 @@ namespace Fortran::semantics { class Scope; +class SemanticsContext; class ProgramTree { public: @@ -34,16 +35,25 @@ public: std::list>; // Build the ProgramTree rooted at one of these program units. - static ProgramTree Build(const parser::ProgramUnit &); - static ProgramTree Build(const parser::MainProgram &); - static ProgramTree Build(const parser::FunctionSubprogram &); - static ProgramTree Build(const parser::SubroutineSubprogram &); - static ProgramTree Build(const parser::SeparateModuleSubprogram &); - static ProgramTree Build(const parser::Module &); - static ProgramTree Build(const parser::Submodule &); - static ProgramTree Build(const parser::BlockData &); - static ProgramTree Build(const parser::CompilerDirective &); - static ProgramTree Build(const parser::OpenACCRoutineConstruct &); + static ProgramTree Build(const parser::ProgramUnit &, SemanticsContext &); + static std::optional Build( + const parser::MainProgram &, SemanticsContext &); + static std::optional Build( + const parser::FunctionSubprogram &, SemanticsContext &); + static std::optional Build( + const parser::SubroutineSubprogram &, SemanticsContext &); + static std::optional Build( + const parser::SeparateModuleSubprogram &, SemanticsContext &); + static std::optional Build( + const parser::Module &, SemanticsContext &); + static std::optional Build( + const parser::Submodule &, SemanticsContext &); + static std::optional Build( + const parser::BlockData &, SemanticsContext &); + static std::optional Build( + const parser::CompilerDirective &, SemanticsContext &); + static std::optional Build( + const parser::OpenACCRoutineConstruct &, SemanticsContext &); ENUM_CLASS(Kind, // kind of node Program, Function, Subroutine, MpSubprogram, Module, Submodule, BlockData) diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index c21cf1bf4d7d..7bd1f4e4e961 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -8889,7 +8889,7 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) { } } } else { - Say(x.source, "Compiler directive was ignored"_warn_en_US); + Say(x.source, "Unrecognized compiler directive was ignored"_warn_en_US); } } @@ -8904,7 +8904,7 @@ bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) { ResolveAccParts(context(), x, &topScope_); return false; } - auto root{ProgramTree::Build(x)}; + auto root{ProgramTree::Build(x, context())}; SetScope(topScope_); ResolveSpecificationParts(root); FinishSpecificationParts(root); diff --git a/flang/test/Parser/unrecognized-dir.f90 b/flang/test/Parser/unrecognized-dir.f90 index ba6fff7562e2..91fbfc9ee3c3 100644 --- a/flang/test/Parser/unrecognized-dir.f90 +++ b/flang/test/Parser/unrecognized-dir.f90 @@ -1,4 +1,10 @@ ! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s -!CHECK: warning: Compiler directive was ignored +!CHECK: warning: Unrecognized compiler directive was ignored !DIR$ Not a recognized directive +program main + contains + !CHECK: warning: Compiler directive ignored here + !DIR$ not in a subprogram + subroutine s + end end -- GitLab From 6fd475fe2e7b15a6f6344430d02c454cf8928a35 Mon Sep 17 00:00:00 2001 From: Peter Klausler <35819229+klausler@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:32:48 -0700 Subject: [PATCH 031/733] [flang][runtime] 'A' output editing for LOGICAL (#89817) We support 'A' output editing for INTEGER and REAL as an extension; it turns out to be used as well for LOGICAL in application code. --- flang/runtime/edit-output.cpp | 5 +++++ flang/unittests/Runtime/RuntimeCrashTest.cpp | 10 ---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/flang/runtime/edit-output.cpp b/flang/runtime/edit-output.cpp index a06ed258f0f1..c3e11e6e4ce6 100644 --- a/flang/runtime/edit-output.cpp +++ b/flang/runtime/edit-output.cpp @@ -822,6 +822,11 @@ RT_API_ATTRS bool EditLogicalOutput( case 'Z': return EditBOZOutput<4>(io, edit, reinterpret_cast(&truth), sizeof truth); + case 'A': { // legacy extension + int truthBits{truth}; + return EditCharacterOutput( + io, edit, reinterpret_cast(&truthBits), sizeof truthBits); + } default: io.GetIoErrorHandler().SignalError(IostatErrorInFormat, "Data edit descriptor '%c' may not be used with a LOGICAL data item", diff --git a/flang/unittests/Runtime/RuntimeCrashTest.cpp b/flang/unittests/Runtime/RuntimeCrashTest.cpp index 0f25cc0ee803..a649051fdca0 100644 --- a/flang/unittests/Runtime/RuntimeCrashTest.cpp +++ b/flang/unittests/Runtime/RuntimeCrashTest.cpp @@ -53,16 +53,6 @@ TEST(TestTerminator, CheckFailedTest) { //------------------------------------------------------------------------------ struct TestIOCrash : CrashHandlerFixture {}; -TEST(TestIOCrash, FormatDescriptorWriteMismatchTest) { - static constexpr int bufferSize{4}; - static char buffer[bufferSize]; - static const char *format{"(A4)"}; - auto *cookie{IONAME(BeginInternalFormattedOutput)( - buffer, bufferSize, format, std::strlen(format))}; - ASSERT_DEATH(IONAME(OutputLogical)(cookie, true), - "Data edit descriptor 'A' may not be used with a LOGICAL data item"); -} - TEST(TestIOCrash, InvalidFormatCharacterTest) { static constexpr int bufferSize{1}; static char buffer[bufferSize]; -- GitLab From fa465b479b09b638e95c8b92ecf358c38910f8b0 Mon Sep 17 00:00:00 2001 From: Peter Klausler <35819229+klausler@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:40:02 -0700 Subject: [PATCH 032/733] [flang][runtime] Improve confusing list-directed REAL(2) output (#89846) List-directed output editing of REAL values will minimize the number of digits that are emitted by calculating a decimal value that, if read back in to a REAL variable of the same kind, would compare equal. This behavior is causing some confusion when applied to list-directed output of large REAL(2) values. Specifically, the value HUGE(0._2) (which is 0x7bff in hex) is exactly 65504, but is edited to 65500. by list-directed output, which selects F0 editing, minimizes the value to 6.55e4, and then formats it without the exponent. This small patch changes that behavior for cases where the output of digit-minimized F editing has no digits after the decimal point and zeroes need to be emitted before it due to the decimal exponent. Digit minimization is disabled in this case and the exact digits are emitted instead. --- flang/runtime/edit-output.cpp | 14 +++++++++++--- flang/unittests/Runtime/NumericalFormatTest.cpp | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/flang/runtime/edit-output.cpp b/flang/runtime/edit-output.cpp index c3e11e6e4ce6..13ab91fc56ea 100644 --- a/flang/runtime/edit-output.cpp +++ b/flang/runtime/edit-output.cpp @@ -446,6 +446,7 @@ RT_API_ATTRS bool RealOutputEditing::EditFOutput(const DataEdit &edit) { fracDigits = sizeof buffer_ - 2; // sign & NUL } } + bool emitTrailingZeroes{!(flags & decimal::Minimize)}; // Multiple conversions may be needed to get the right number of // effective rounded fractional digits. bool canIncrease{true}; @@ -526,11 +527,18 @@ RT_API_ATTRS bool RealOutputEditing::EditFOutput(const DataEdit &edit) { } int digitsBeforePoint{std::max(0, std::min(expo, convertedDigits))}; int zeroesBeforePoint{std::max(0, expo - digitsBeforePoint)}; + if (zeroesBeforePoint > 0 && (flags & decimal::Minimize)) { + // If a minimized result looks like an integer, emit all of + // its digits rather than clipping some to zeroes. + // This can happen with HUGE(0._2) == 65504._2. + flags &= ~decimal::Minimize; + continue; + } int zeroesAfterPoint{std::min(fracDigits, std::max(0, -expo))}; int digitsAfterPoint{convertedDigits - digitsBeforePoint}; - int trailingZeroes{flags & decimal::Minimize - ? 0 - : std::max(0, fracDigits - (zeroesAfterPoint + digitsAfterPoint))}; + int trailingZeroes{emitTrailingZeroes + ? std::max(0, fracDigits - (zeroesAfterPoint + digitsAfterPoint)) + : 0}; if (digitsBeforePoint + zeroesBeforePoint + zeroesAfterPoint + digitsAfterPoint + trailingZeroes == 0) { diff --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp index dee4dda4a228..2a9f8f8d1dc4 100644 --- a/flang/unittests/Runtime/NumericalFormatTest.cpp +++ b/flang/unittests/Runtime/NumericalFormatTest.cpp @@ -958,3 +958,20 @@ TEST(IOApiTests, EditDoubleInputValues) { << "', want " << want << ", got " << u.raw; } } + +// regression test for confusing digit minimization +TEST(IOApiTests, ConfusingMinimization) { + char buffer[8]{}; + auto cookie{IONAME(BeginInternalListOutput)(buffer, sizeof buffer)}; + StaticDescriptor<0> staticDescriptor; + Descriptor &desc{staticDescriptor.descriptor()}; + std::uint16_t x{0x7bff}; // HUGE(0._2) + desc.Establish(TypeCode{CFI_type_half_float}, sizeof x, &x, 0, nullptr); + desc.Check(); + EXPECT_TRUE(IONAME(OutputDescriptor)(cookie, desc)); + auto status{IONAME(EndIoStatement)(cookie)}; + EXPECT_EQ(status, 0); + std::string got{std::string{buffer, sizeof buffer}}; + EXPECT_TRUE(CompareFormattedStrings(" 65504. ", got)) + << "expected ' 65504. ', got '" << got << '\''; // not 65500.! +} -- GitLab From 8b512e525d3adc56da626a6e4f16c3b2f602aade Mon Sep 17 00:00:00 2001 From: Peter Klausler <35819229+klausler@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:47:29 -0700 Subject: [PATCH 033/733] [flang][preprocessor] Support \ as line continuation (#89970) When prescanning a Fortran source file with preprocessing enabled in free source form, interpret a line-ending backslash as a source line continuation marker as a C preprocessor would. This usage isn't completely portable, but it is supported by GNU Fortran and appears in the source for FPM package manager. --- flang/docs/Preprocessing.md | 3 +++ flang/include/flang/Parser/preprocessor.h | 1 + flang/lib/Parser/prescan.cpp | 18 +++++++++++++----- flang/lib/Parser/prescan.h | 1 + flang/test/Preprocessing/backslash-contin1.F90 | 8 ++++++++ 5 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 flang/test/Preprocessing/backslash-contin1.F90 diff --git a/flang/docs/Preprocessing.md b/flang/docs/Preprocessing.md index 3c523472f39b..0b70d857833c 100644 --- a/flang/docs/Preprocessing.md +++ b/flang/docs/Preprocessing.md @@ -93,6 +93,9 @@ local: * If a `#define` or `#undef` directive appears among continuation lines, it may or may not affect text in the continued statement that appeared before the directive. +* A backslash at the end of a free form source line is a continuation + marker, with no space skipping or special handling of a leading `&` + on the next line. ## Behavior that few compilers properly support (or none), but should: diff --git a/flang/include/flang/Parser/preprocessor.h b/flang/include/flang/Parser/preprocessor.h index 630d5273d427..c3076435be5f 100644 --- a/flang/include/flang/Parser/preprocessor.h +++ b/flang/include/flang/Parser/preprocessor.h @@ -81,6 +81,7 @@ public: void Undefine(std::string macro); bool IsNameDefined(const CharBlock &); bool IsFunctionLikeDefinition(const CharBlock &); + bool AnyDefinitions() const { return !definitions_.empty(); } // When called with partialFunctionLikeMacro not null, MacroReplacement() // and ReplaceMacros() handle an unclosed function-like macro reference diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp index 96db3955299f..2d46eae531b1 100644 --- a/flang/lib/Parser/prescan.cpp +++ b/flang/lib/Parser/prescan.cpp @@ -29,15 +29,18 @@ Prescanner::Prescanner(Messages &messages, CookedSource &cooked, Preprocessor &preprocessor, common::LanguageFeatureControl lfc) : messages_{messages}, cooked_{cooked}, preprocessor_{preprocessor}, allSources_{preprocessor_.allSources()}, features_{lfc}, + backslashFreeFormContinuation_{preprocessor.AnyDefinitions()}, encoding_{allSources_.encoding()} {} Prescanner::Prescanner(const Prescanner &that) : messages_{that.messages_}, cooked_{that.cooked_}, preprocessor_{that.preprocessor_}, allSources_{that.allSources_}, - features_{that.features_}, inFixedForm_{that.inFixedForm_}, + features_{that.features_}, + backslashFreeFormContinuation_{that.backslashFreeFormContinuation_}, + inFixedForm_{that.inFixedForm_}, fixedFormColumnLimit_{that.fixedFormColumnLimit_}, - encoding_{that.encoding_}, prescannerNesting_{that.prescannerNesting_ + - 1}, + encoding_{that.encoding_}, + prescannerNesting_{that.prescannerNesting_ + 1}, skipLeadingAmpersand_{that.skipLeadingAmpersand_}, compilerDirectiveBloomFilter_{that.compilerDirectiveBloomFilter_}, compilerDirectiveSentinels_{that.compilerDirectiveSentinels_} {} @@ -1226,9 +1229,14 @@ bool Prescanner::Continuation(bool mightNeedFixedFormSpace) { } else { return FreeFormContinuation(); } - } else { - return false; + } else if (*at_ == '\\' && at_ + 2 == nextLine_ && + backslashFreeFormContinuation_ && !inFixedForm_ && nextLine_ < limit_) { + // cpp-like handling of \ at end of a free form source line + BeginSourceLine(nextLine_); + NextLine(); + return true; } + return false; } std::optional diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h index 581980001bcc..3ee4c5a2c69e 100644 --- a/flang/lib/Parser/prescan.h +++ b/flang/lib/Parser/prescan.h @@ -197,6 +197,7 @@ private: Preprocessor &preprocessor_; AllSources &allSources_; common::LanguageFeatureControl features_; + bool backslashFreeFormContinuation_{false}; bool inFixedForm_{false}; int fixedFormColumnLimit_{72}; Encoding encoding_{Encoding::UTF_8}; diff --git a/flang/test/Preprocessing/backslash-contin1.F90 b/flang/test/Preprocessing/backslash-contin1.F90 new file mode 100644 index 000000000000..cf2ed36370da --- /dev/null +++ b/flang/test/Preprocessing/backslash-contin1.F90 @@ -0,0 +1,8 @@ +! RUN: %flang -E %s | FileCheck %s +print *, \ + "hello, \ +world" +end +!CHECK: print *, "hello, world" +!CHECK: end + -- GitLab From 14339aba9ca3299f0f76999e0e8f42a7e1eacb10 Mon Sep 17 00:00:00 2001 From: Peter Klausler <35819229+klausler@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:57:58 -0700 Subject: [PATCH 034/733] [flang] Catch error on REPEAT(x,NCOPIES=array) (#89993) The NCOPIES= argument to the intrinsic function REPEAT must be a scalar integer. Fixes https://github.com/llvm/llvm-project/issues/89851. --- flang/lib/Evaluate/intrinsics.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp index f07f94b1a022..1b73cadb682d 100644 --- a/flang/lib/Evaluate/intrinsics.cpp +++ b/flang/lib/Evaluate/intrinsics.cpp @@ -777,7 +777,9 @@ static const IntrinsicInterface genericIntrinsicFunction[]{ {"identity", SameType, Rank::scalar, Optionality::optional}, {"ordered", AnyLogical, Rank::scalar, Optionality::optional}}, SameType, Rank::scalar, IntrinsicClass::transformationalFunction}, - {"repeat", {{"string", SameCharNoLen, Rank::scalar}, {"ncopies", AnyInt}}, + {"repeat", + {{"string", SameCharNoLen, Rank::scalar}, + {"ncopies", AnyInt, Rank::scalar}}, SameCharNoLen, Rank::scalar, IntrinsicClass::transformationalFunction}, {"reshape", {{"source", SameType, Rank::array}, {"shape", AnyInt, Rank::shape}, -- GitLab From 9961311216f7b22be4fc1221b70ebd1d63bb9843 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Thu, 25 Apr 2024 01:00:31 +0200 Subject: [PATCH 035/733] Revert "[MC] Rename temporary symbols of empty name to ".L0 "" (#90002) Reverts llvm/llvm-project#89693 This broke the premerge bot (bolt tests failing) --- lld/test/ELF/mips-eh_frame-pic.s | 4 +-- llvm/include/llvm/Object/ELFObjectFile.h | 5 +-- llvm/lib/MC/ELFObjectWriter.cpp | 6 ---- llvm/test/CodeGen/RISCV/fixups-diff.ll | 2 +- .../LoongArch/dwarf-loongarch-relocs.ll | 18 +++++------ .../DebugInfo/RISCV/dwarf-riscv-relocs.ll | 12 +++---- .../test/DebugInfo/RISCV/relax-debug-frame.ll | 10 +++--- ...ary-symbol.s => riscv-empty-name-symbol.s} | 5 ++- .../JITLink/RISCV/anonymous_symbol.s | 2 +- llvm/test/MC/ELF/RISCV/gen-dwarf.s | 26 +++++++-------- llvm/test/MC/RISCV/cfi-advance.s | 32 ++++--------------- llvm/test/MC/RISCV/fde-reloc.s | 2 +- llvm/test/MC/RISCV/scoped-relaxation.s | 6 ++-- 13 files changed, 52 insertions(+), 78 deletions(-) rename llvm/test/DebugInfo/Symbolize/ELF/{riscv-temporary-symbol.s => riscv-empty-name-symbol.s} (71%) diff --git a/lld/test/ELF/mips-eh_frame-pic.s b/lld/test/ELF/mips-eh_frame-pic.s index c04dbdf57b08..a84c36b0e5ec 100644 --- a/lld/test/ELF/mips-eh_frame-pic.s +++ b/lld/test/ELF/mips-eh_frame-pic.s @@ -36,8 +36,8 @@ # RELOCS: .rel{{a?}}.eh_frame { # ABS32-RELOCS-NEXT: 0x1C R_MIPS_32 .text # ABS64-RELOCS-NEXT: 0x1C R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE .text -# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE .L0 -# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 .L0 +# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE +# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 # RELOCS-NEXT: } # ABS64-EH-FRAME: Augmentation data: 0C diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 4494d9b96189..1d457be93741 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -801,8 +801,9 @@ Expected ELFObjectFile::getSymbolFlags(DataRefImpl Sym) const { } else if (EF.getHeader().e_machine == ELF::EM_RISCV) { if (Expected NameOrErr = getSymbolName(Sym)) { StringRef Name = *NameOrErr; - // Mark fake labels (used for label differences) and mapping symbols. - if (Name == ".L0 " || Name.starts_with("$d") || Name.starts_with("$x")) + // Mark empty name symbols (used for label differences) and mapping + // symbols. + if (Name.empty() || Name.starts_with("$d") || Name.starts_with("$x")) Result |= SymbolRef::SF_FormatSpecific; } else { // TODO: Actually report errors helpfully. diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index b8ef2654ed6e..005521bad6e0 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -725,13 +725,7 @@ void ELFWriter::computeSymbolTable( HasLargeSectionIndex = true; } - // Temporary symbols generated for certain assembler features (.eh_frame, - // .debug_line) of an empty name may be referenced by relocations due to - // linker relaxation. Rename them to ".L0 " to match the gas fake label name - // and allow ld/objcopy --discard-locals to discard such symbols. StringRef Name = Symbol.getName(); - if (Name.empty()) - Name = ".L0 "; // Sections have their own string table if (Symbol.getType() != ELF::STT_SECTION) { diff --git a/llvm/test/CodeGen/RISCV/fixups-diff.ll b/llvm/test/CodeGen/RISCV/fixups-diff.ll index 84a7d18ed150..cc1c87b1fe37 100644 --- a/llvm/test/CodeGen/RISCV/fixups-diff.ll +++ b/llvm/test/CodeGen/RISCV/fixups-diff.ll @@ -27,7 +27,7 @@ entry: ; CHECK: } ; CHECK: Section {{.*}} .rela.eh_frame { -; CHECK-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 +; CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 ; CHECK-NEXT: } !llvm.dbg.cu = !{!0} diff --git a/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll b/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll index d28836d56037..d6a1d8d6e136 100644 --- a/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll +++ b/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll @@ -18,21 +18,21 @@ ; RELOCS-BOTH: Section ({{.*}}) .rela.debug_frame { ; RELOCS-NORL-NEXT: 0x1C R_LARCH_32 .debug_frame 0x0 ; RELOCS-NORL-NEXT: 0x20 R_LARCH_64 .text 0x0 -; RELOCS-ENRL-NEXT: 0x1C R_LARCH_32 .L0 0x0 -; RELOCS-ENRL-NEXT: 0x20 R_LARCH_64 .L0 0x0 -; RELOCS-ENRL-NEXT: 0x28 R_LARCH_ADD64 .L0 0x0 -; RELOCS-ENRL-NEXT: 0x28 R_LARCH_SUB64 .L0 0x0 -; RELOCS-ENRL-NEXT: 0x3F R_LARCH_ADD6 .L0 0x0 -; RELOCS-ENRL-NEXT: 0x3F R_LARCH_SUB6 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x1C R_LARCH_32 0x0 +; RELOCS-ENRL-NEXT: 0x20 R_LARCH_64 0x0 +; RELOCS-ENRL-NEXT: 0x28 R_LARCH_ADD64 0x0 +; RELOCS-ENRL-NEXT: 0x28 R_LARCH_SUB64 0x0 +; RELOCS-ENRL-NEXT: 0x3F R_LARCH_ADD6 0x0 +; RELOCS-ENRL-NEXT: 0x3F R_LARCH_SUB6 0x0 ; RELOCS-BOTH-NEXT: } ; RELOCS-BOTH: Section ({{.*}}) .rela.debug_line { ; RELOCS-BOTH-NEXT: 0x22 R_LARCH_32 .debug_line_str 0x0 ; RELOCS-BOTH-NEXT: 0x31 R_LARCH_32 .debug_line_str 0x2 ; RELOCS-BOTH-NEXT: 0x46 R_LARCH_32 .debug_line_str 0x1B ; RELOCS-NORL-NEXT: 0x4F R_LARCH_64 .text 0x0 -; RELOCS-ENRL-NEXT: 0x4F R_LARCH_64 .L0 0x0 -; RELOCS-ENRL-NEXT: 0x5F R_LARCH_ADD16 .L0 0x0 -; RELOCS-ENRL-NEXT: 0x5F R_LARCH_SUB16 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x4F R_LARCH_64 0x0 +; RELOCS-ENRL-NEXT: 0x5F R_LARCH_ADD16 0x0 +; RELOCS-ENRL-NEXT: 0x5F R_LARCH_SUB16 0x0 ; RELOCS-BOTH-NEXT: } ; RELOCS-BOTH-NEXT: ] diff --git a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll index 99594b5e01e9..e5de1713f4e0 100644 --- a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll +++ b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll @@ -6,14 +6,14 @@ ; Check that we actually have relocations, otherwise this is kind of pointless. ; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_info { -; READOBJ-RELOCS: 0x1B R_RISCV_ADD32 .L0 0x0 -; READOBJ-RELOCS-NEXT: 0x1B R_RISCV_SUB32 .L0 0x0 +; READOBJ-RELOCS: 0x1B R_RISCV_ADD32 0x0 +; READOBJ-RELOCS-NEXT: 0x1B R_RISCV_SUB32 0x0 ; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_frame { -; READOBJ-RELOCS: 0x20 R_RISCV_ADD32 .L0 0x0 -; READOBJ-RELOCS-NEXT: 0x20 R_RISCV_SUB32 .L0 0x0 +; READOBJ-RELOCS: 0x20 R_RISCV_ADD32 0x0 +; READOBJ-RELOCS-NEXT: 0x20 R_RISCV_SUB32 0x0 ; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_line { -; READOBJ-RELOCS: 0x5A R_RISCV_ADD16 .L0 0x0 -; READOBJ-RELOCS-NEXT: 0x5A R_RISCV_SUB16 .L0 0x0 +; READOBJ-RELOCS: 0x5A R_RISCV_ADD16 0x0 +; READOBJ-RELOCS-NEXT: 0x5A R_RISCV_SUB16 0x0 ; Check that we can print the source, even with relocations. ; OBJDUMP-SOURCE: Disassembly of section .text: diff --git a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll index ffef0ec23406..f655a7c0a7ef 100644 --- a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll +++ b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll @@ -4,11 +4,11 @@ ; RUN: | FileCheck -check-prefix=RELAX-DWARFDUMP %s ; ; RELAX: Section ({{.*}}) .rela.eh_frame { -; RELAX-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 -; RELAX-NEXT: 0x30 R_RISCV_32_PCREL .L0 0x0 -; RELAX-NEXT: 0x44 R_RISCV_32_PCREL .L0 0x0 -; RELAX-NEXT: 0x48 R_RISCV_ADD32 .L0 0x0 -; RELAX-NEXT: 0x48 R_RISCV_SUB32 .L0 0x0 +; RELAX-NEXT: 0x1C R_RISCV_32_PCREL 0x0 +; RELAX-NEXT: 0x30 R_RISCV_32_PCREL 0x0 +; RELAX-NEXT: 0x44 R_RISCV_32_PCREL 0x0 +; RELAX-NEXT: 0x48 R_RISCV_ADD32 0x0 +; RELAX-NEXT: 0x48 R_RISCV_SUB32 0x0 ; RELAX-NEXT: } ; RELAX-DWARFDUMP-NOT: error: failed to compute relocation diff --git a/llvm/test/DebugInfo/Symbolize/ELF/riscv-temporary-symbol.s b/llvm/test/DebugInfo/Symbolize/ELF/riscv-empty-name-symbol.s similarity index 71% rename from llvm/test/DebugInfo/Symbolize/ELF/riscv-temporary-symbol.s rename to llvm/test/DebugInfo/Symbolize/ELF/riscv-empty-name-symbol.s index 0b54f104ab95..1e0fa8a30618 100644 --- a/llvm/test/DebugInfo/Symbolize/ELF/riscv-temporary-symbol.s +++ b/llvm/test/DebugInfo/Symbolize/ELF/riscv-empty-name-symbol.s @@ -1,11 +1,10 @@ # REQUIRES: riscv-registered-target -## Ignore .L0 symbols that are generated by LLVM integrated assembler and GNU -## assembler for .debug_line/.eh_frame related assembler directives. +## Ignore empty name symbols. # RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t # RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYM -# SYM: 0000000000000004 0 NOTYPE LOCAL DEFAULT [[#]] .L0 {{$}} +# SYM: 0000000000000004 0 NOTYPE LOCAL DEFAULT [[#]] {{$}} # SYM: 0000000000000000 0 NOTYPE GLOBAL DEFAULT [[#]] foo ## Make sure we test at an address larger than or equal to an empty name symbol. diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s b/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s index e7114e4d643c..a5038022dfe0 100644 --- a/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s @@ -7,7 +7,7 @@ # the section start and section end. So that by relocating these symbol, the section length # can be calculated. # -# CHECK: Creating defined graph symbol for ELF symbol ".L0 " +# CHECK: Creating defined graph symbol for ELF symbol "" # CHECK: Creating defined graph symbol for ELF symbol "main" .text .globl main diff --git a/llvm/test/MC/ELF/RISCV/gen-dwarf.s b/llvm/test/MC/ELF/RISCV/gen-dwarf.s index 34d02f5da44f..342ed1cc0e7e 100644 --- a/llvm/test/MC/ELF/RISCV/gen-dwarf.s +++ b/llvm/test/MC/ELF/RISCV/gen-dwarf.s @@ -40,28 +40,28 @@ # CHECK-NEXT: 0x00000020: [DW_RLE_end_of_list ] # RELOC: Section ([[#]]) .rela.eh_frame { -# RELOC-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 -# RELOC-NEXT: 0x20 R_RISCV_ADD32 .L0 0x0 -# RELOC-NEXT: 0x20 R_RISCV_SUB32 .L0 0x0 -# RELOC-NEXT: 0x25 R_RISCV_SET6 .L0 0x0 -# RELOC-NEXT: 0x25 R_RISCV_SUB6 .L0 0x0 -# RELOC-NEXT: 0x34 R_RISCV_32_PCREL .L0 0x0 +# RELOC-NEXT: 0x1C R_RISCV_32_PCREL 0x0 +# RELOC-NEXT: 0x20 R_RISCV_ADD32 0x0 +# RELOC-NEXT: 0x20 R_RISCV_SUB32 0x0 +# RELOC-NEXT: 0x25 R_RISCV_SET6 0x0 +# RELOC-NEXT: 0x25 R_RISCV_SUB6 0x0 +# RELOC-NEXT: 0x34 R_RISCV_32_PCREL 0x0 # RELOC-NEXT: } # RELOC: Section ([[#]]) .rela.debug_rnglists { # RELOC-NEXT: 0xD R_RISCV_64 .text.foo 0x0 -# RELOC-NEXT: 0x15 R_RISCV_SET_ULEB128 .L0 0x0 +# RELOC-NEXT: 0x15 R_RISCV_SET_ULEB128 0x0 # RELOC-NEXT: 0x15 R_RISCV_SUB_ULEB128 .text.foo 0x0 # RELOC-NEXT: 0x17 R_RISCV_64 .text.bar 0x0 # RELOC-NEXT: } # RELOC: Section ([[#]]) .rela.debug_line { -# RELOC: R_RISCV_ADD16 .L0 0x0 -# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0 -# RELOC-NEXT: R_RISCV_ADD16 .L0 0x0 -# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0 -# RELOC-NEXT: R_RISCV_ADD16 .L0 0x0 -# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0 +# RELOC: R_RISCV_ADD16 0x0 +# RELOC-NEXT: R_RISCV_SUB16 0x0 +# RELOC-NEXT: R_RISCV_ADD16 0x0 +# RELOC-NEXT: R_RISCV_SUB16 0x0 +# RELOC-NEXT: R_RISCV_ADD16 0x0 +# RELOC-NEXT: R_RISCV_SUB16 0x0 # RELOC: } # RELOC: Hex dump of section '.eh_frame': diff --git a/llvm/test/MC/RISCV/cfi-advance.s b/llvm/test/MC/RISCV/cfi-advance.s index b99af38f553a..c4af390be757 100644 --- a/llvm/test/MC/RISCV/cfi-advance.s +++ b/llvm/test/MC/RISCV/cfi-advance.s @@ -1,27 +1,13 @@ # RUN: llvm-mc -filetype=obj -triple riscv32 %s -o %t.o -# RUN: llvm-readelf -sr %t.o | FileCheck %s +# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=CHECK %s # RUN: llvm-dwarfdump --debug-frame %t.o 2>&1 \ # RUN: | FileCheck -check-prefix=CHECK-DWARFDUMP %s - -# CHECK: Relocation section '.rela.text1' at offset {{.*}} contains 1 entries: -# CHECK-NEXT: Offset Info Type Sym. Value Symbol's Name + Addend -# CHECK-NEXT: 00000000 00000313 R_RISCV_CALL_PLT 00000004 .L0 + 0 -# CHECK-EMPTY: -# CHECK-NEXT: Relocation section '.rela.eh_frame' at offset {{.*}} contains 3 entries: -# CHECK: Offset Info Type Sym. Value Symbol's Name + Addend -# CHECK-NEXT: 0000001c 00000139 R_RISCV_32_PCREL 00000000 .L0 + 0 -# CHECK-NEXT: 00000035 00000b35 R_RISCV_SET6 00010178 .L0 + 0 -# CHECK-NEXT: 00000035 00000934 R_RISCV_SUB6 0001016e .L0 + 0 -# CHECK-EMPTY: -# CHECK: Symbol table '.symtab' contains 15 entries: -# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name -# CHECK-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND -# CHECK-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}} -# CHECK: 3: 00000004 0 NOTYPE LOCAL DEFAULT 2 .L0{{$}} -# CHECK: 9: 0001016e 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}} -# CHECK: 11: 00010178 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}} - +# CHECK: .rela.eh_frame { +# CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 +# CHECK-NEXT: 0x35 R_RISCV_SET6 0x0 +# CHECK-NEXT: 0x35 R_RISCV_SUB6 0x0 +# CHECK-NEXT: } # CHECK-DWARFDUMP: DW_CFA_advance_loc1: 104 # CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8 # CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc2: 259 @@ -37,9 +23,6 @@ test: .cfi_startproc nop -## This looks similar to fake label names ".L0 ". Even if this is ".L0 ", -## the assembler will not conflate it with fake labels. -.L0: .zero 100, 0x90 .cfi_def_cfa_offset 8 nop @@ -53,6 +36,3 @@ test: .cfi_def_cfa_offset 8 nop .cfi_endproc - -.section .text1,"ax" -call .L0 diff --git a/llvm/test/MC/RISCV/fde-reloc.s b/llvm/test/MC/RISCV/fde-reloc.s index 81ec426c8b61..1db8929e0747 100644 --- a/llvm/test/MC/RISCV/fde-reloc.s +++ b/llvm/test/MC/RISCV/fde-reloc.s @@ -12,7 +12,7 @@ func: .cfi_endproc # CHECK: Section (4) .rela.eh_frame { -# CHECK-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 +# CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 # CHECK-NEXT: } # CHECK: Hex dump of section '.eh_frame': # CHECK-NEXT: 0x00000000 10000000 00000000 017a5200 017c0101 diff --git a/llvm/test/MC/RISCV/scoped-relaxation.s b/llvm/test/MC/RISCV/scoped-relaxation.s index 56394fd80532..0b797ee5aca5 100644 --- a/llvm/test/MC/RISCV/scoped-relaxation.s +++ b/llvm/test/MC/RISCV/scoped-relaxation.s @@ -9,7 +9,7 @@ .dword function - . # CHECK: 0x0 R_RISCV_ADD64 function 0x0 -# CHECK-NEXT: 0x0 R_RISCV_SUB64 .L0 0x0 +# CHECK-NEXT: 0x0 R_RISCV_SUB64 0x0 # Relaxed reference, this will resolve to a pair of `RISCV_ADD64` and # `RISCV_SUB64` relocation. @@ -19,7 +19,7 @@ .option pop # CHECK: 0x8 R_RISCV_ADD64 function 0x0 -# CHECK-NEXT: 0x8 R_RISCV_SUB64 .L0 0x0 +# CHECK-NEXT: 0x8 R_RISCV_SUB64 0x0 # Unrelaxed reference, this will resolve to a pair of `RISCV_ADD64` and # `RISCV_SUB64` relocation due to relaxation being sticky to the file. @@ -29,6 +29,6 @@ .option pop # CHECK: 0x10 R_RISCV_ADD64 function 0x0 -# CHECK-NEXT: 0x10 R_RISCV_SUB64 .L0 0x0 +# CHECK-NEXT: 0x10 R_RISCV_SUB64 0x0 # CHECK: } -- GitLab From 49586eacd306c70f81986644921e12e55dd7422f Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Wed, 24 Apr 2024 16:07:02 -0700 Subject: [PATCH 036/733] remove duplicate td_library import (#90003) Reverts bad part of one line from https://github.com/llvm/llvm-project/commit/ae22ac95354629baca45d979038d73a4ce40d081#diff-9b538219c38ed73e193087a031284f10c62de8692ccc0efbe8c670fe9bfe868f --- utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel index b98f7eb5613a..0ebfcbe284bd 100644 --- a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel @@ -4,7 +4,7 @@ load("@bazel_skylib//rules:expand_template.bzl", "expand_template") load("//llvm:lit_test.bzl", "package_path") -load("//mlir:tblgen.bzl", "gentbl_cc_library", "td_library", "gentbl_sharded_ops", "td_library") +load("//mlir:tblgen.bzl", "gentbl_cc_library", "gentbl_sharded_ops", "td_library") package( default_visibility = ["//visibility:public"], @@ -423,9 +423,9 @@ cc_library( "//mlir:SideEffectInterfaces", "//mlir:Support", "//mlir:TensorDialect", - "//mlir:TranslateLib", "//mlir:TransformUtils", "//mlir:Transforms", + "//mlir:TranslateLib", "//mlir:ValueBoundsOpInterface", "//mlir:ViewLikeInterface", ], -- GitLab From a10d67f9fb559d0c35a12b2d26974636bbf642c0 Mon Sep 17 00:00:00 2001 From: Yinying Li Date: Wed, 24 Apr 2024 16:20:25 -0700 Subject: [PATCH 037/733] [mlir][sparse] Enable explicit and implicit value in sparse encoding (#88975) 1. Explicit value means the non-zero value in a sparse tensor. If explicitVal is set, then all the non-zero values in the tensor have the same explicit value. The default value Attribute() indicates that it is not set. 2. Implicit value means the "zero" value in a sparse tensor. If implicitVal is set, then the "zero" value in the tensor is equal to the implicit value. For now, we only support `0` as the implicit value but it could be extended in the future. The default value Attribute() indicates that the implicit value is `0` (same type as the tensor element type). Example: ``` #CSR = #sparse_tensor.encoding<{ map = (d0, d1) -> (d0 : dense, d1 : compressed), posWidth = 64, crdWidth = 64, explicitVal = 1 : i64, implicitVal = 0 : i64 }> ``` Note: this PR tests that implicitVal could be set to other values as well. The following PR will add verifier and reject any value that's not zero for implicitVal. --- mlir/include/mlir-c/Dialect/SparseTensor.h | 11 +- .../SparseTensor/IR/SparseTensorAttrDefs.td | 55 +++++++++- .../SparseTensor/IR/SparseTensorType.h | 22 ++++ .../Bindings/Python/DialectSparseTensor.cpp | 27 ++++- mlir/lib/CAPI/Dialect/SparseTensor.cpp | 26 +++-- .../SparseTensor/IR/SparseTensorDialect.cpp | 101 +++++++++++++++--- mlir/test/CAPI/sparse_tensor.c | 17 ++- .../SparseTensor/roundtrip_encoding.mlir | 58 ++++++++++ .../python/dialects/sparse_tensor/dialect.py | 73 ++++++++----- 9 files changed, 333 insertions(+), 57 deletions(-) diff --git a/mlir/include/mlir-c/Dialect/SparseTensor.h b/mlir/include/mlir-c/Dialect/SparseTensor.h index 52ca7ba8a161..125469f57c5f 100644 --- a/mlir/include/mlir-c/Dialect/SparseTensor.h +++ b/mlir/include/mlir-c/Dialect/SparseTensor.h @@ -53,7 +53,8 @@ mlirAttributeIsASparseTensorEncodingAttr(MlirAttribute attr); MLIR_CAPI_EXPORTED MlirAttribute mlirSparseTensorEncodingAttrGet( MlirContext ctx, intptr_t lvlRank, MlirSparseTensorLevelType const *lvlTypes, MlirAffineMap dimToLvl, - MlirAffineMap lvlTodim, int posWidth, int crdWidth); + MlirAffineMap lvlTodim, int posWidth, int crdWidth, + MlirAttribute explicitVal, MlirAttribute implicitVal); /// Returns the level-rank of the `sparse_tensor.encoding` attribute. MLIR_CAPI_EXPORTED intptr_t @@ -85,6 +86,14 @@ mlirSparseTensorEncodingAttrGetPosWidth(MlirAttribute attr); MLIR_CAPI_EXPORTED int mlirSparseTensorEncodingAttrGetCrdWidth(MlirAttribute attr); +/// Returns the explicit value of the `sparse_tensor.encoding` attribute. +MLIR_CAPI_EXPORTED MlirAttribute +mlirSparseTensorEncodingAttrGetExplicitVal(MlirAttribute attr); + +/// Returns the implicit value of the `sparse_tensor.encoding` attribute. +MLIR_CAPI_EXPORTED MlirAttribute +mlirSparseTensorEncodingAttrGetImplicitVal(MlirAttribute attr); + MLIR_CAPI_EXPORTED unsigned mlirSparseTensorEncodingAttrGetStructuredN(MlirSparseTensorLevelType lvlType); diff --git a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td index 4a9b9169ae4b..eefa4c71bbd2 100644 --- a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td +++ b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td @@ -167,7 +167,7 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding", - **soa** : only applicable to singleton levels, fuses the singleton level in SoA (structure of arrays) scheme. - In addition to the map, the following two fields are optional: + In addition to the map, the following fields are optional: - The required bitwidth for position storage (integral offsets into the sparse storage scheme). A narrow width reduces the memory @@ -183,6 +183,23 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding", coordinate over all levels). The choices are `8`, `16`, `32`, `64`, or, the default, `0` to indicate a native bitwidth. + - The explicit value for the sparse tensor. If explicitVal is set, + then all the non-zero values in the tensor have the same explicit value. + The default value Attribute() indicates that it is not set. This + is useful for binary-valued sparse tensors whose values can either + be an implicit value (0 by default) or an explicit value (such as 1). + In this approach, we don't store explicit/implicit values, and metadata + (such as position and coordinate arrays) alone fully defines the original tensor. + This yields additional savings for the storage requirements, + as well as for the computational time, since we skip operating on + implicit values and can constant fold the explicit values where they are used. + + - The implicit value for the sparse tensor. If implicitVal is set, + then the "zero" value in the tensor is equal to the implicit value. + For now, we only support `0` as the implicit value but it could be + extended in the future. The default value Attribute() indicates that + the implicit value is `0` (same type as the tensor element type). + Examples: ```mlir @@ -226,6 +243,15 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding", }> ... tensor<8x8xf64, #DCSC> ... + // Doubly compressed sparse column storage with specific + // explicit and implicit values. + #DCSC = #sparse_tensor.encoding<{ + map = (i, j) -> (j : compressed, i : compressed), + explicitVal = 1 : i64, + implicitVal = 0 : i64 + }> + ... tensor<8x8xi64, #DCSC> ... + // Block sparse row storage (2x3 blocks). #BSR = #sparse_tensor.encoding<{ map = ( i, j ) -> @@ -307,6 +333,12 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding", // The required bitwidth for coordinate storage. "unsigned":$crdWidth, + // The required explicit value. + "::mlir::Attribute":$explicitVal, + + // The required implicit value. + "::mlir::Attribute":$implicitVal, + // A slice attribute for each dimension of the tensor type. ArrayRefParameter< "::mlir::sparse_tensor::SparseTensorDimSliceAttr", @@ -319,7 +351,9 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding", CArg<"AffineMap", "{}">:$dimToLvl, CArg<"AffineMap", "{}">:$lvlToDim, CArg<"unsigned", "0">:$posWidth, - CArg<"unsigned", "0">:$crdWidth), [{ + CArg<"unsigned", "0">:$crdWidth, + CArg<"::mlir::Attribute", "{}">:$explicitVal, + CArg<"::mlir::Attribute", "{}">:$implicitVal), [{ if (!dimToLvl) { dimToLvl = ::mlir::AffineMap::getMultiDimIdentityMap(lvlTypes.size(), $_ctxt); } @@ -327,6 +361,7 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding", lvlToDim = ::mlir::sparse_tensor::inferLvlToDim(dimToLvl, $_ctxt); } return $_get($_ctxt, lvlTypes, dimToLvl, lvlToDim, posWidth, crdWidth, + explicitVal, implicitVal, ArrayRef<::mlir::sparse_tensor::SparseTensorDimSliceAttr>{}); }]> ]; @@ -353,6 +388,22 @@ def SparseTensorEncodingAttr : SparseTensor_Attr<"SparseTensorEncoding", /// reset to the default, and all other fields inherited from `this`. SparseTensorEncodingAttr withoutBitWidths() const; + /// Constructs a new encoding with the given explicit value + /// and all other fields inherited from `this`. + SparseTensorEncodingAttr withExplicitVal(Attribute explicitVal) const; + + /// Constructs a new encoding with the explicit value + /// reset to the default, and all other fields inherited from `this`. + SparseTensorEncodingAttr withoutExplicitVal() const; + + /// Constructs a new encoding with the given implicit value + /// and all other fields inherited from `this`. + SparseTensorEncodingAttr withImplicitVal(Attribute implicitVal) const; + + /// Constructs a new encoding with the implicit value + /// reset to the default, and all other fields inherited from `this`. + SparseTensorEncodingAttr withoutImplicitVal() const; + /// Constructs a new encoding with the given dimSlices, and all /// other fields inherited from `this`. SparseTensorEncodingAttr withDimSlices(ArrayRef<::mlir::sparse_tensor::SparseTensorDimSliceAttr> dimSlices) const; diff --git a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorType.h b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorType.h index 825d89a408fe..34d99913fbd5 100644 --- a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorType.h +++ b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorType.h @@ -115,6 +115,22 @@ public: return withEncoding(enc.withoutBitWidths()); } + SparseTensorType withExplicitVal(Attribute explicitVal) const { + return withEncoding(enc.withExplicitVal(explicitVal)); + } + + SparseTensorType withoutExplicitVal() const { + return withEncoding(enc.withoutExplicitVal()); + } + + SparseTensorType withImplicitVal(Attribute implicitVal) const { + return withEncoding(enc.withImplicitVal(implicitVal)); + } + + SparseTensorType withoutImplicitVal() const { + return withEncoding(enc.withoutImplicitVal()); + } + SparseTensorType withDimSlices(ArrayRef dimSlices) const { return withEncoding(enc.withDimSlices(dimSlices)); @@ -327,6 +343,12 @@ public: /// Returns the position-overhead bitwidth, defaulting to zero. unsigned getPosWidth() const { return enc ? enc.getPosWidth() : 0; } + /// Returns the explicit value, defaulting to null Attribute for unset. + Attribute getExplicitVal() const { return enc.getExplicitVal(); } + + /// Returns the implicit value, defaulting to null Attribute for 0. + Attribute getImplicitVal() const { return enc.getImplicitVal(); } + /// Returns the coordinate-overhead MLIR type, defaulting to `IndexType`. Type getCrdType() const { return enc.getCrdElemType(); } diff --git a/mlir/lib/Bindings/Python/DialectSparseTensor.cpp b/mlir/lib/Bindings/Python/DialectSparseTensor.cpp index 171faf9e0087..584981cfe99b 100644 --- a/mlir/lib/Bindings/Python/DialectSparseTensor.cpp +++ b/mlir/lib/Bindings/Python/DialectSparseTensor.cpp @@ -42,16 +42,19 @@ static void populateDialectSparseTensorSubmodule(const py::module &m) { [](py::object cls, std::vector lvlTypes, std::optional dimToLvl, std::optional lvlToDim, int posWidth, int crdWidth, - MlirContext context) { + std::optional explicitVal, + std::optional implicitVal, MlirContext context) { return cls(mlirSparseTensorEncodingAttrGet( context, lvlTypes.size(), lvlTypes.data(), dimToLvl ? *dimToLvl : MlirAffineMap{nullptr}, lvlToDim ? *lvlToDim : MlirAffineMap{nullptr}, posWidth, - crdWidth)); + crdWidth, explicitVal ? *explicitVal : MlirAttribute{nullptr}, + implicitVal ? *implicitVal : MlirAttribute{nullptr})); }, py::arg("cls"), py::arg("lvl_types"), py::arg("dim_to_lvl"), py::arg("lvl_to_dim"), py::arg("pos_width"), py::arg("crd_width"), - py::arg("context") = py::none(), + py::arg("explicit_val") = py::none(), + py::arg("implicit_val") = py::none(), py::arg("context") = py::none(), "Gets a sparse_tensor.encoding from parameters.") .def_classmethod( "build_level_type", @@ -97,6 +100,24 @@ static void populateDialectSparseTensorSubmodule(const py::module &m) { mlirSparseTensorEncodingAttrGetPosWidth) .def_property_readonly("crd_width", mlirSparseTensorEncodingAttrGetCrdWidth) + .def_property_readonly( + "explicit_val", + [](MlirAttribute self) -> std::optional { + MlirAttribute ret = + mlirSparseTensorEncodingAttrGetExplicitVal(self); + if (mlirAttributeIsNull(ret)) + return {}; + return ret; + }) + .def_property_readonly( + "implicit_val", + [](MlirAttribute self) -> std::optional { + MlirAttribute ret = + mlirSparseTensorEncodingAttrGetImplicitVal(self); + if (mlirAttributeIsNull(ret)) + return {}; + return ret; + }) .def_property_readonly( "structured_n", [](MlirAttribute self) -> unsigned { diff --git a/mlir/lib/CAPI/Dialect/SparseTensor.cpp b/mlir/lib/CAPI/Dialect/SparseTensor.cpp index 3ae06f220c52..19171d64d409 100644 --- a/mlir/lib/CAPI/Dialect/SparseTensor.cpp +++ b/mlir/lib/CAPI/Dialect/SparseTensor.cpp @@ -44,18 +44,20 @@ bool mlirAttributeIsASparseTensorEncodingAttr(MlirAttribute attr) { return isa(unwrap(attr)); } -MlirAttribute -mlirSparseTensorEncodingAttrGet(MlirContext ctx, intptr_t lvlRank, - MlirSparseTensorLevelType const *lvlTypes, - MlirAffineMap dimToLvl, MlirAffineMap lvlToDim, - int posWidth, int crdWidth) { +MlirAttribute mlirSparseTensorEncodingAttrGet( + MlirContext ctx, intptr_t lvlRank, + MlirSparseTensorLevelType const *lvlTypes, MlirAffineMap dimToLvl, + MlirAffineMap lvlToDim, int posWidth, int crdWidth, + MlirAttribute explicitVal, MlirAttribute implicitVal) { SmallVector cppLvlTypes; + cppLvlTypes.reserve(lvlRank); for (intptr_t l = 0; l < lvlRank; ++l) cppLvlTypes.push_back(static_cast(lvlTypes[l])); - return wrap(SparseTensorEncodingAttr::get(unwrap(ctx), cppLvlTypes, - unwrap(dimToLvl), unwrap(lvlToDim), - posWidth, crdWidth)); + + return wrap(SparseTensorEncodingAttr::get( + unwrap(ctx), cppLvlTypes, unwrap(dimToLvl), unwrap(lvlToDim), posWidth, + crdWidth, unwrap(explicitVal), unwrap(implicitVal))); } MlirAffineMap mlirSparseTensorEncodingAttrGetDimToLvl(MlirAttribute attr) { @@ -91,6 +93,14 @@ int mlirSparseTensorEncodingAttrGetCrdWidth(MlirAttribute attr) { return cast(unwrap(attr)).getCrdWidth(); } +MlirAttribute mlirSparseTensorEncodingAttrGetExplicitVal(MlirAttribute attr) { + return wrap(cast(unwrap(attr)).getExplicitVal()); +} + +MlirAttribute mlirSparseTensorEncodingAttrGetImplicitVal(MlirAttribute attr) { + return wrap(cast(unwrap(attr)).getImplicitVal()); +} + MlirSparseTensorLevelType mlirSparseTensorEncodingAttrBuildLvlType( enum MlirSparseTensorLevelFormat lvlFmt, const enum MlirSparseTensorLevelPropertyNondefault *properties, diff --git a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp index b1d44559fa5a..028a69da10c1 100644 --- a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp +++ b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp @@ -326,9 +326,9 @@ SparseTensorDimSliceAttr::verify(function_ref emitError, SparseTensorEncodingAttr SparseTensorEncodingAttr::withDimToLvl(AffineMap dimToLvl) const { assert(getImpl() && "Uninitialized SparseTensorEncodingAttr"); - return SparseTensorEncodingAttr::get(getContext(), getLvlTypes(), dimToLvl, - AffineMap(), getPosWidth(), - getCrdWidth()); + return SparseTensorEncodingAttr::get( + getContext(), getLvlTypes(), dimToLvl, AffineMap(), getPosWidth(), + getCrdWidth(), getExplicitVal(), getImplicitVal()); } SparseTensorEncodingAttr @@ -344,20 +344,44 @@ SparseTensorEncodingAttr SparseTensorEncodingAttr::withBitWidths(unsigned posWidth, unsigned crdWidth) const { assert(getImpl() && "Uninitialized SparseTensorEncodingAttr"); - return SparseTensorEncodingAttr::get(getContext(), getLvlTypes(), - getDimToLvl(), getLvlToDim(), posWidth, - crdWidth); + return SparseTensorEncodingAttr::get( + getContext(), getLvlTypes(), getDimToLvl(), getLvlToDim(), posWidth, + crdWidth, getExplicitVal(), getImplicitVal()); } SparseTensorEncodingAttr SparseTensorEncodingAttr::withoutBitWidths() const { return withBitWidths(0, 0); } +SparseTensorEncodingAttr +SparseTensorEncodingAttr::withExplicitVal(Attribute explicitVal) const { + assert(getImpl() && "Uninitialized SparseTensorEncodingAttr"); + return SparseTensorEncodingAttr::get( + getContext(), getLvlTypes(), getDimToLvl(), getLvlToDim(), getPosWidth(), + getCrdWidth(), explicitVal, getImplicitVal()); +} + +SparseTensorEncodingAttr SparseTensorEncodingAttr::withoutExplicitVal() const { + return withExplicitVal(Attribute()); +} + +SparseTensorEncodingAttr +SparseTensorEncodingAttr::withImplicitVal(Attribute implicitVal) const { + assert(getImpl() && "Uninitialized SparseTensorEncodingAttr"); + return SparseTensorEncodingAttr::get( + getContext(), getLvlTypes(), getDimToLvl(), getLvlToDim(), getPosWidth(), + getCrdWidth(), getExplicitVal(), implicitVal); +} + +SparseTensorEncodingAttr SparseTensorEncodingAttr::withoutImplicitVal() const { + return withImplicitVal(Attribute()); +} + SparseTensorEncodingAttr SparseTensorEncodingAttr::withDimSlices( ArrayRef dimSlices) const { - return SparseTensorEncodingAttr::get(getContext(), getLvlTypes(), - getDimToLvl(), getLvlToDim(), - getPosWidth(), getCrdWidth(), dimSlices); + return SparseTensorEncodingAttr::get( + getContext(), getLvlTypes(), getDimToLvl(), getLvlToDim(), getPosWidth(), + getCrdWidth(), getExplicitVal(), getImplicitVal(), dimSlices); } SparseTensorEncodingAttr SparseTensorEncodingAttr::withoutDimSlices() const { @@ -553,8 +577,11 @@ Attribute SparseTensorEncodingAttr::parse(AsmParser &parser, Type type) { AffineMap lvlToDim = {}; unsigned posWidth = 0; unsigned crdWidth = 0; + Attribute explicitVal; + Attribute implicitVal; StringRef attrName; - SmallVector keys = {"map", "posWidth", "crdWidth"}; + SmallVector keys = {"map", "posWidth", "crdWidth", + "explicitVal", "implicitVal"}; while (succeeded(parser.parseOptionalKeyword(&attrName))) { // Detect admissible keyword. auto *it = find(keys, attrName); @@ -628,6 +655,36 @@ Attribute SparseTensorEncodingAttr::parse(AsmParser &parser, Type type) { crdWidth = intAttr.getInt(); break; } + case 3: { // explicitVal + Attribute attr; + if (failed(parser.parseAttribute(attr))) + return {}; + if (auto result = llvm::dyn_cast(attr)) { + explicitVal = result; + } else if (auto result = llvm::dyn_cast(attr)) { + explicitVal = result; + } else { + parser.emitError(parser.getNameLoc(), + "expected a numeric value for explicitVal"); + return {}; + } + break; + } + case 4: { // implicitVal + Attribute attr; + if (failed(parser.parseAttribute(attr))) + return {}; + if (auto result = llvm::dyn_cast(attr)) { + implicitVal = result; + } else if (auto result = llvm::dyn_cast(attr)) { + implicitVal = result; + } else { + parser.emitError(parser.getNameLoc(), + "expected a numeric value for implicitVal"); + return {}; + } + break; + } } // switch // Only last item can omit the comma. if (parser.parseOptionalComma().failed()) @@ -646,7 +703,7 @@ Attribute SparseTensorEncodingAttr::parse(AsmParser &parser, Type type) { } return parser.getChecked( parser.getContext(), lvlTypes, dimToLvl, lvlToDim, posWidth, crdWidth, - dimSlices); + explicitVal, implicitVal, dimSlices); } void SparseTensorEncodingAttr::print(AsmPrinter &printer) const { @@ -666,6 +723,11 @@ void SparseTensorEncodingAttr::print(AsmPrinter &printer) const { printer << ", posWidth = " << getPosWidth(); if (getCrdWidth()) printer << ", crdWidth = " << getCrdWidth(); + if (getExplicitVal()) { + printer << ", explicitVal = " << getExplicitVal(); + } + if (getImplicitVal()) + printer << ", implicitVal = " << getImplicitVal(); printer << " }>"; } @@ -715,7 +777,8 @@ void SparseTensorEncodingAttr::printLevels(AffineMap &map, AsmPrinter &printer, LogicalResult SparseTensorEncodingAttr::verify( function_ref emitError, ArrayRef lvlTypes, AffineMap dimToLvl, AffineMap lvlToDim, unsigned posWidth, - unsigned crdWidth, ArrayRef dimSlices) { + unsigned crdWidth, Attribute explicitVal, Attribute implicitVal, + ArrayRef dimSlices) { if (!acceptBitWidth(posWidth)) return emitError() << "unexpected position bitwidth: " << posWidth; if (!acceptBitWidth(crdWidth)) @@ -831,7 +894,8 @@ LogicalResult SparseTensorEncodingAttr::verifyEncoding( // Check structural integrity. In particular, this ensures that the // level-rank is coherent across all the fields. if (failed(verify(emitError, getLvlTypes(), getDimToLvl(), getLvlToDim(), - getPosWidth(), getCrdWidth(), getDimSlices()))) + getPosWidth(), getCrdWidth(), getExplicitVal(), + getImplicitVal(), getDimSlices()))) return failure(); // Check integrity with tensor type specifics. In particular, we // need only check that the dimension-rank of the tensor agrees with @@ -921,9 +985,9 @@ mlir::sparse_tensor::SparseTensorType::getCOOType(bool ordered) const { // Ends by a unique singleton level. lvlTypes.push_back(*buildLevelType(LevelFormat::Singleton, ordered, true)); } - auto enc = SparseTensorEncodingAttr::get(getContext(), lvlTypes, - getDimToLvl(), getLvlToDim(), - getPosWidth(), getCrdWidth()); + auto enc = SparseTensorEncodingAttr::get( + getContext(), lvlTypes, getDimToLvl(), getLvlToDim(), getPosWidth(), + getCrdWidth(), getExplicitVal(), getImplicitVal()); return RankedTensorType::get(getDimShape(), getElementType(), enc); } @@ -1115,7 +1179,10 @@ getNormalizedEncodingForSpecifier(SparseTensorEncodingAttr enc) { // `getPosWidth` and `getCrdWidth`. It allows us to reuse the same SSA // value for different bitwidth, it also avoids casting between index and // integer (returned by DimOp) - 0, 0, enc.getDimSlices()); + 0, 0, + Attribute(), // explicitVal (irrelevant to storage specifier) + Attribute(), // implicitVal (irrelevant to storage specifier) + enc.getDimSlices()); } StorageSpecifierType diff --git a/mlir/test/CAPI/sparse_tensor.c b/mlir/test/CAPI/sparse_tensor.c index f241e0e5c2fb..22b7052b732a 100644 --- a/mlir/test/CAPI/sparse_tensor.c +++ b/mlir/test/CAPI/sparse_tensor.c @@ -27,7 +27,7 @@ static int testRoundtripEncoding(MlirContext ctx) { const char *originalAsm = "#sparse_tensor.encoding<{ " "map = [s0](d0, d1) -> (s0 : dense, d0 : compressed, d1 : compressed), " - "posWidth = 32, crdWidth = 64 }>"; + "posWidth = 32, crdWidth = 64, explicitVal = 1 : i64}>"; // clang-format on MlirAttribute originalAttr = mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString(originalAsm)); @@ -56,8 +56,21 @@ static int testRoundtripEncoding(MlirContext ctx) { // CHECK: crdWidth: 64 int crdWidth = mlirSparseTensorEncodingAttrGetCrdWidth(originalAttr); fprintf(stderr, "crdWidth: %d\n", crdWidth); + + // CHECK: explicitVal: 1 : i64 + MlirAttribute explicitVal = + mlirSparseTensorEncodingAttrGetExplicitVal(originalAttr); + fprintf(stderr, "explicitVal: "); + mlirAttributeDump(explicitVal); + // CHECK: implicitVal: <> + MlirAttribute implicitVal = + mlirSparseTensorEncodingAttrGetImplicitVal(originalAttr); + fprintf(stderr, "implicitVal: "); + mlirAttributeDump(implicitVal); + MlirAttribute newAttr = mlirSparseTensorEncodingAttrGet( - ctx, lvlRank, lvlTypes, dimToLvl, lvlToDim, posWidth, crdWidth); + ctx, lvlRank, lvlTypes, dimToLvl, lvlToDim, posWidth, crdWidth, + explicitVal, implicitVal); mlirAttributeDump(newAttr); // For debugging filecheck output. // CHECK: equal: 1 fprintf(stderr, "equal: %d\n", mlirAttributeEqual(originalAttr, newAttr)); diff --git a/mlir/test/Dialect/SparseTensor/roundtrip_encoding.mlir b/mlir/test/Dialect/SparseTensor/roundtrip_encoding.mlir index 66e61afd897d..7eeda9a98802 100644 --- a/mlir/test/Dialect/SparseTensor/roundtrip_encoding.mlir +++ b/mlir/test/Dialect/SparseTensor/roundtrip_encoding.mlir @@ -22,6 +22,64 @@ func.func private @sparse_csr(tensor) // ----- +#CSR_OnlyOnes = #sparse_tensor.encoding<{ + map = (d0, d1) -> (d0 : dense, d1 : compressed), + posWidth = 64, + crdWidth = 64, + explicitVal = 1.0 : f32, + implicitVal = 0.0 : f32 +}> + +// CHECK: #[[$CSR_OnlyOnes:.*]] = #sparse_tensor.encoding<{ map = (d0, d1) -> (d0 : dense, d1 : compressed), posWidth = 64, crdWidth = 64, explicitVal = 1.000000e+00 : f32, implicitVal = 0.000000e+00 : f32 }> +// CHECK-LABEL: func private @sparse_csr( +// CHECK-SAME: tensor) +func.func private @sparse_csr(tensor) + +// ----- + +#CSR_OnlyOnes = #sparse_tensor.encoding<{ + map = (d0, d1) -> (d0 : dense, d1 : compressed), + explicitVal = 1.0 : f64, + implicitVal = 0.0 : f64 +}> + +// CHECK: #[[$CSR_OnlyOnes:.*]] = #sparse_tensor.encoding<{ map = (d0, d1) -> (d0 : dense, d1 : compressed), explicitVal = 1.000000e+00 : f64, implicitVal = 0.000000e+00 : f64 }> +// CHECK-LABEL: func private @sparse_csr( +// CHECK-SAME: tensor) +func.func private @sparse_csr(tensor) + +// ----- + +#CSR_OnlyOnes = #sparse_tensor.encoding<{ + map = (d0, d1) -> (d0 : dense, d1 : compressed), + posWidth = 64, + crdWidth = 64, + explicitVal = 1 : i32, + implicitVal = 0 : i32 +}> + +// CHECK: #[[$CSR_OnlyOnes:.*]] = #sparse_tensor.encoding<{ map = (d0, d1) -> (d0 : dense, d1 : compressed), posWidth = 64, crdWidth = 64, explicitVal = 1 : i32, implicitVal = 0 : i32 }> +// CHECK-LABEL: func private @sparse_csr( +// CHECK-SAME: tensor) +func.func private @sparse_csr(tensor) + +// ----- + +#CSR_OnlyOnes = #sparse_tensor.encoding<{ + map = (d0, d1) -> (d0 : dense, d1 : compressed), + posWidth = 64, + crdWidth = 64, + explicitVal = 1 : i64, + implicitVal = 0 : i64 +}> + +// CHECK: #[[$CSR_OnlyOnes:.*]] = #sparse_tensor.encoding<{ map = (d0, d1) -> (d0 : dense, d1 : compressed), posWidth = 64, crdWidth = 64, explicitVal = 1 : i64, implicitVal = 0 : i64 }> +// CHECK-LABEL: func private @sparse_csr( +// CHECK-SAME: tensor) +func.func private @sparse_csr(tensor) + +// ----- + #BCSR = #sparse_tensor.encoding<{ map = (d0, d1, d2) -> (d0 : batch, d1: dense, d2 : compressed), }> diff --git a/mlir/test/python/dialects/sparse_tensor/dialect.py b/mlir/test/python/dialects/sparse_tensor/dialect.py index 5666d090c3d5..3cc4575eb3e2 100644 --- a/mlir/test/python/dialects/sparse_tensor/dialect.py +++ b/mlir/test/python/dialects/sparse_tensor/dialect.py @@ -2,6 +2,7 @@ from mlir.ir import * from mlir.dialects import sparse_tensor as st +import textwrap def run(f): @@ -15,13 +16,18 @@ def run(f): def testEncodingAttr1D(): with Context() as ctx: parsed = Attribute.parse( - "#sparse_tensor.encoding<{" - " map = (d0) -> (d0 : compressed)," - " posWidth = 16," - " crdWidth = 32" - "}>" + textwrap.dedent( + """\ + #sparse_tensor.encoding<{ + map = (d0) -> (d0 : compressed), + posWidth = 16, + crdWidth = 32, + explicitVal = 1.0 : f64 + }>\ + """ + ) ) - # CHECK: #sparse_tensor.encoding<{ map = (d0) -> (d0 : compressed), posWidth = 16, crdWidth = 32 }> + # CHECK: #sparse_tensor.encoding<{ map = (d0) -> (d0 : compressed), posWidth = 16, crdWidth = 32, explicitVal = 1.000000e+00 : f64 }> print(parsed) casted = st.EncodingAttr(parsed) @@ -38,9 +44,16 @@ def testEncodingAttr1D(): print(f"pos_width: {casted.pos_width}") # CHECK: crd_width: 32 print(f"crd_width: {casted.crd_width}") + # CHECK: explicit_val: 1.000000e+00 + print(f"explicit_val: {casted.explicit_val}") + # CHECK: implicit_val: None + print(f"implicit_val: {casted.implicit_val}") - created = st.EncodingAttr.get(casted.lvl_types, None, None, 0, 0) - # CHECK: #sparse_tensor.encoding<{ map = (d0) -> (d0 : compressed) }> + new_explicit_val = FloatAttr.get_f64(1.0) + created = st.EncodingAttr.get( + casted.lvl_types, None, None, 0, 0, new_explicit_val + ) + # CHECK: #sparse_tensor.encoding<{ map = (d0) -> (d0 : compressed), explicitVal = 1.000000e+00 : f64 }> print(created) # CHECK: created_equal: False print(f"created_equal: {created == casted}") @@ -57,12 +70,16 @@ def testEncodingAttr1D(): def testEncodingAttrStructure(): with Context() as ctx: parsed = Attribute.parse( - "#sparse_tensor.encoding<{" - " map = (d0, d1) -> (d0 : dense, d1 floordiv 4 : dense," - " d1 mod 4 : structured[2, 4])," - " posWidth = 16," - " crdWidth = 32" - "}>" + textwrap.dedent( + """\ + #sparse_tensor.encoding<{ + map = (d0, d1) -> (d0 : dense, d1 floordiv 4 : dense, + d1 mod 4 : structured[2, 4]), + posWidth = 16, + crdWidth = 32, + }>\ + """ + ) ) # CHECK: #sparse_tensor.encoding<{ map = (d0, d1) -> (d0 : dense, d1 floordiv 4 : dense, d1 mod 4 : structured[2, 4]), posWidth = 16, crdWidth = 32 }> print(parsed) @@ -144,11 +161,15 @@ def testEncodingAttrStructure(): def testEncodingAttr2D(): with Context() as ctx: parsed = Attribute.parse( - "#sparse_tensor.encoding<{" - " map = (d0, d1) -> (d1 : dense, d0 : compressed)," - " posWidth = 8," - " crdWidth = 32" - "}>" + textwrap.dedent( + """\ + #sparse_tensor.encoding<{ + map = (d0, d1) -> (d1 : dense, d0 : compressed), + posWidth = 8, + crdWidth = 32, + }>\ + """ + ) ) # CHECK: #sparse_tensor.encoding<{ map = (d0, d1) -> (d1 : dense, d0 : compressed), posWidth = 8, crdWidth = 32 }> print(parsed) @@ -187,11 +208,15 @@ def testEncodingAttrOnTensorType(): with Context() as ctx, Location.unknown(): encoding = st.EncodingAttr( Attribute.parse( - "#sparse_tensor.encoding<{" - " map = (d0) -> (d0 : compressed), " - " posWidth = 64," - " crdWidth = 32" - "}>" + textwrap.dedent( + """\ + #sparse_tensor.encoding<{ + map = (d0) -> (d0 : compressed), + posWidth = 64, + crdWidth = 32, + }>\ + """ + ) ) ) tt = RankedTensorType.get((1024,), F32Type.get(), encoding=encoding) -- GitLab From 4c8ec8f8bc3fb4dda4fd36c3b2ad745bd3451970 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Wed, 24 Apr 2024 16:25:35 -0700 Subject: [PATCH 038/733] [memprof] Reduce schema for Version2 (#89876) Curently, the compiler only uses several fields of MemoryInfoBlock. Serializing all fields into the indexed MemProf file simply wastes storage. This patch limits the schema down to four fields for Version2 by default. It retains the old behavior of serializing all fields via: llvm-profdata merge --memprof-version=2 --memprof-full-schema This patch reduces the size of the indexed MemProf profile I have by 40% (1.6GB down to 1.0GB). --- .../llvm/ProfileData/InstrProfWriter.h | 7 +- llvm/include/llvm/ProfileData/MemProf.h | 9 +- llvm/lib/ProfileData/InstrProfWriter.cpp | 23 +-- .../tools/llvm-profdata/memprof-merge-v0.test | 3 + llvm/tools/llvm-profdata/llvm-profdata.cpp | 6 +- llvm/unittests/ProfileData/InstrProfTest.cpp | 142 ++++++++++++++---- 6 files changed, 145 insertions(+), 45 deletions(-) diff --git a/llvm/include/llvm/ProfileData/InstrProfWriter.h b/llvm/include/llvm/ProfileData/InstrProfWriter.h index b0ae8f364fca..08db8fa6e7ef 100644 --- a/llvm/include/llvm/ProfileData/InstrProfWriter.h +++ b/llvm/include/llvm/ProfileData/InstrProfWriter.h @@ -85,11 +85,15 @@ private: // The MemProf version we should write. memprof::IndexedVersion MemProfVersionRequested; + // Whether to serialize the full schema. + bool MemProfFullSchema; + public: InstrProfWriter( bool Sparse = false, uint64_t TemporalProfTraceReservoirSize = 0, uint64_t MaxTemporalProfTraceLength = 0, bool WritePrevVersion = false, - memprof::IndexedVersion MemProfVersionRequested = memprof::Version0); + memprof::IndexedVersion MemProfVersionRequested = memprof::Version0, + bool MemProfFullSchema = false); ~InstrProfWriter(); StringMap &getProfileData() { return FunctionData; } @@ -203,6 +207,7 @@ public: void setMemProfVersionRequested(memprof::IndexedVersion Version) { MemProfVersionRequested = Version; } + void setMemProfFullSchema(bool Full) { MemProfFullSchema = Full; } // Compute the overlap b/w this object and Other. Program level result is // stored in Overlap and function level result is stored in FuncLevelOverlap. void overlapRecord(NamedInstrProfRecord &&Other, OverlapStats &Overlap, diff --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h index 37019bcab544..a8e98f8bb138 100644 --- a/llvm/include/llvm/ProfileData/MemProf.h +++ b/llvm/include/llvm/ProfileData/MemProf.h @@ -117,7 +117,7 @@ struct PortableMemInfoBlock { void clear() { *this = PortableMemInfoBlock(); } // Returns the full schema currently in use. - static MemProfSchema getSchema() { + static MemProfSchema getFullSchema() { MemProfSchema List; #define MIBEntryDef(NameTag, Name, Type) List.push_back(Meta::Name); #include "llvm/ProfileData/MIBEntryDef.inc" @@ -125,6 +125,13 @@ struct PortableMemInfoBlock { return List; } + // Returns the schema consisting of the fields currently consumed by the + // compiler. + static MemProfSchema getHotColdSchema() { + return {Meta::AllocCount, Meta::TotalSize, Meta::TotalLifetime, + Meta::TotalLifetimeAccessDensity}; + } + bool operator==(const PortableMemInfoBlock &Other) const { #define MIBEntryDef(NameTag, Name, Type) \ if (Other.get##Name() != get##Name()) \ diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp index 4a6fc9d64b69..70ae57f77dae 100644 --- a/llvm/lib/ProfileData/InstrProfWriter.cpp +++ b/llvm/lib/ProfileData/InstrProfWriter.cpp @@ -184,12 +184,13 @@ public: InstrProfWriter::InstrProfWriter( bool Sparse, uint64_t TemporalProfTraceReservoirSize, uint64_t MaxTemporalProfTraceLength, bool WritePrevVersion, - memprof::IndexedVersion MemProfVersionRequested) + memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema) : Sparse(Sparse), MaxTemporalProfTraceLength(MaxTemporalProfTraceLength), TemporalProfTraceReservoirSize(TemporalProfTraceReservoirSize), InfoObj(new InstrProfRecordWriterTrait()), WritePrevVersion(WritePrevVersion), - MemProfVersionRequested(MemProfVersionRequested) {} + MemProfVersionRequested(MemProfVersionRequested), + MemProfFullSchema(MemProfFullSchema) {} InstrProfWriter::~InstrProfWriter() { delete InfoObj; } @@ -507,7 +508,7 @@ static Error writeMemProfV0( OS.write(0ULL); // Reserve space for the memprof frame payload offset. OS.write(0ULL); // Reserve space for the memprof frame table offset. - auto Schema = memprof::PortableMemInfoBlock::getSchema(); + auto Schema = memprof::PortableMemInfoBlock::getFullSchema(); writeMemProfSchema(OS, Schema); uint64_t RecordTableOffset = @@ -533,7 +534,7 @@ static Error writeMemProfV1( OS.write(0ULL); // Reserve space for the memprof frame payload offset. OS.write(0ULL); // Reserve space for the memprof frame table offset. - auto Schema = memprof::PortableMemInfoBlock::getSchema(); + auto Schema = memprof::PortableMemInfoBlock::getFullSchema(); writeMemProfSchema(OS, Schema); uint64_t RecordTableOffset = @@ -554,7 +555,8 @@ static Error writeMemProfV2( &MemProfRecordData, llvm::MapVector &MemProfFrameData, llvm::MapVector> - &MemProfCallStackData) { + &MemProfCallStackData, + bool MemProfFullSchema) { OS.write(memprof::Version2); uint64_t HeaderUpdatePos = OS.tell(); OS.write(0ULL); // Reserve space for the memprof record table offset. @@ -563,7 +565,9 @@ static Error writeMemProfV2( OS.write(0ULL); // Reserve space for the memprof call stack payload offset. OS.write(0ULL); // Reserve space for the memprof call stack table offset. - auto Schema = memprof::PortableMemInfoBlock::getSchema(); + auto Schema = memprof::PortableMemInfoBlock::getHotColdSchema(); + if (MemProfFullSchema) + Schema = memprof::PortableMemInfoBlock::getFullSchema(); writeMemProfSchema(OS, Schema); uint64_t RecordTableOffset = @@ -605,7 +609,7 @@ static Error writeMemProf( llvm::MapVector &MemProfFrameData, llvm::MapVector> &MemProfCallStackData, - memprof::IndexedVersion MemProfVersionRequested) { + memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema) { switch (MemProfVersionRequested) { case memprof::Version0: @@ -614,7 +618,7 @@ static Error writeMemProf( return writeMemProfV1(OS, MemProfRecordData, MemProfFrameData); case memprof::Version2: return writeMemProfV2(OS, MemProfRecordData, MemProfFrameData, - MemProfCallStackData); + MemProfCallStackData, MemProfFullSchema); } return make_error( @@ -733,7 +737,8 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) { if (static_cast(ProfileKind & InstrProfKind::MemProf)) { MemProfSectionStart = OS.tell(); if (auto E = writeMemProf(OS, MemProfRecordData, MemProfFrameData, - MemProfCallStackData, MemProfVersionRequested)) + MemProfCallStackData, MemProfVersionRequested, + MemProfFullSchema)) return E; } diff --git a/llvm/test/tools/llvm-profdata/memprof-merge-v0.test b/llvm/test/tools/llvm-profdata/memprof-merge-v0.test index 03ccbdd42efd..28f65e0781bc 100644 --- a/llvm/test/tools/llvm-profdata/memprof-merge-v0.test +++ b/llvm/test/tools/llvm-profdata/memprof-merge-v0.test @@ -16,6 +16,9 @@ RUN: llvm-profdata show %t.prof.v1 | FileCheck %s RUN: llvm-profdata merge %t.proftext %p/Inputs/basic.memprofraw --memprof-version=2 --profiled-binary %p/Inputs/basic.memprofexe -o %t.prof.v2 RUN: llvm-profdata show %t.prof.v2 | FileCheck %s +RUN: llvm-profdata merge %t.proftext %p/Inputs/basic.memprofraw --memprof-version=2 --memprof-full-schema --profiled-binary %p/Inputs/basic.memprofexe -o %t.prof.v2 +RUN: llvm-profdata show %t.prof.v2 | FileCheck %s + For now we only check the validity of the instrumented profile since we don't have a way to display the contents of the memprof indexed format yet. diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp index 78daf9f7dc10..ec046ebfab13 100644 --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -308,6 +308,10 @@ cl::opt MemProfVersionRequested( clEnumValN(memprof::Version1, "1", "version 1"), clEnumValN(memprof::Version2, "2", "version 2"))); +cl::opt MemProfFullSchema( + "memprof-full-schema", cl::Hidden, cl::sub(MergeSubcommand), + cl::desc("Use the full schema for serialization"), cl::init(false)); + // Options specific to overlap subcommand. cl::opt BaseFilename(cl::Positional, cl::Required, cl::desc(""), @@ -600,7 +604,7 @@ struct WriterContext { SmallSet &WriterErrorCodes, uint64_t ReservoirSize = 0, uint64_t MaxTraceLength = 0) : Writer(IsSparse, ReservoirSize, MaxTraceLength, DoWritePrevVersion, - MemProfVersionRequested), + MemProfVersionRequested, MemProfFullSchema), ErrLock(ErrLock), WriterErrorCodes(WriterErrorCodes) {} }; diff --git a/llvm/unittests/ProfileData/InstrProfTest.cpp b/llvm/unittests/ProfileData/InstrProfTest.cpp index 73ba0a23ea5f..edc427dcbc45 100644 --- a/llvm/unittests/ProfileData/InstrProfTest.cpp +++ b/llvm/unittests/ProfileData/InstrProfTest.cpp @@ -370,12 +370,31 @@ static CallStackIdMapTy getCallStackMapping() { return Mapping; } +// Populate all of the fields of MIB. +MemInfoBlock makeFullMIB() { + MemInfoBlock MIB; +#define MIBEntryDef(NameTag, Name, Type) MIB.NameTag; +#include "llvm/ProfileData/MIBEntryDef.inc" +#undef MIBEntryDef + return MIB; +} + +// Populate those fields returned by getHotColdSchema. +MemInfoBlock makePartialMIB() { + MemInfoBlock MIB; + MIB.AllocCount = 1; + MIB.TotalSize = 5; + MIB.TotalLifetime = 10; + MIB.TotalLifetimeAccessDensity = 23; + return MIB; +} + IndexedMemProfRecord makeRecord( std::initializer_list> AllocFrames, std::initializer_list> CallSiteFrames, - const MemInfoBlock &Block = MemInfoBlock()) { + const MemInfoBlock &Block = makeFullMIB()) { llvm::memprof::IndexedMemProfRecord MR; for (const auto &Frames : AllocFrames) MR.AllocSites.emplace_back(Frames, llvm::memprof::hashCallStack(Frames), @@ -388,7 +407,7 @@ IndexedMemProfRecord makeRecord( IndexedMemProfRecord makeRecordV2(std::initializer_list<::llvm::memprof::CallStackId> AllocFrames, std::initializer_list<::llvm::memprof::CallStackId> CallSiteFrames, - const MemInfoBlock &Block = MemInfoBlock()) { + const MemInfoBlock &Block) { llvm::memprof::IndexedMemProfRecord MR; for (const auto &CSId : AllocFrames) // We don't populate IndexedAllocationInfo::CallStack because we use it only @@ -476,15 +495,56 @@ TEST_F(InstrProfTest, test_memprof_v0) { EXPECT_THAT(WantRecord, EqualsRecord(Record)); } -TEST_F(InstrProfTest, test_memprof_v2) { +struct CallStackIdConverter { + std::optional LastUnmappedFrameId; + std::optional LastUnmappedCSId; + + const FrameIdMapTy &IdToFrameMap; + const CallStackIdMapTy &CSIdToCallStackMap; + + CallStackIdConverter() = delete; + CallStackIdConverter(const FrameIdMapTy &IdToFrameMap, + const CallStackIdMapTy &CSIdToCallStackMap) + : IdToFrameMap(IdToFrameMap), CSIdToCallStackMap(CSIdToCallStackMap) {} + + llvm::SmallVector + operator()(::llvm::memprof::CallStackId CSId) { + auto IdToFrameCallback = [&](const memprof::FrameId Id) { + auto Iter = IdToFrameMap.find(Id); + if (Iter == IdToFrameMap.end()) { + LastUnmappedFrameId = Id; + return memprof::Frame(0, 0, 0, false); + } + return Iter->second; + }; + + llvm::SmallVector Frames; + auto CSIter = CSIdToCallStackMap.find(CSId); + if (CSIter == CSIdToCallStackMap.end()) { + LastUnmappedCSId = CSId; + } else { + const ::llvm::SmallVector<::llvm::memprof::FrameId> &CS = + CSIter->getSecond(); + Frames.reserve(CS.size()); + for (::llvm::memprof::FrameId Id : CS) + Frames.push_back(IdToFrameCallback(Id)); + } + return Frames; + } +}; + +TEST_F(InstrProfTest, test_memprof_v2_full_schema) { + const MemInfoBlock MIB = makeFullMIB(); + Writer.setMemProfVersionRequested(memprof::Version2); + Writer.setMemProfFullSchema(true); ASSERT_THAT_ERROR(Writer.mergeProfileKind(InstrProfKind::MemProf), Succeeded()); const IndexedMemProfRecord IndexedMR = makeRecordV2( /*AllocFrames=*/{0x111, 0x222}, - /*CallSiteFrames=*/{0x333}); + /*CallSiteFrames=*/{0x333}, MIB); const FrameIdMapTy IdToFrameMap = getFrameMapping(); const auto CSIdToCallStackMap = getCallStackMapping(); for (const auto &I : IdToFrameMap) { @@ -502,38 +562,54 @@ TEST_F(InstrProfTest, test_memprof_v2) { ASSERT_THAT_ERROR(RecordOr.takeError(), Succeeded()); const memprof::MemProfRecord &Record = RecordOr.get(); - std::optional LastUnmappedFrameId; - auto IdToFrameCallback = [&](const memprof::FrameId Id) { - auto Iter = IdToFrameMap.find(Id); - if (Iter == IdToFrameMap.end()) { - LastUnmappedFrameId = Id; - return memprof::Frame(0, 0, 0, false); - } - return Iter->second; - }; + CallStackIdConverter CSIdConv(IdToFrameMap, CSIdToCallStackMap); - std::optional<::llvm::memprof::CallStackId> LastUnmappedCSId; - auto CSIdToCallStackCallback = [&](::llvm::memprof::CallStackId CSId) { - llvm::SmallVector Frames; - auto CSIter = CSIdToCallStackMap.find(CSId); - if (CSIter == CSIdToCallStackMap.end()) { - LastUnmappedCSId = CSId; - } else { - const ::llvm::SmallVector<::llvm::memprof::FrameId> &CS = - CSIter->getSecond(); - Frames.reserve(CS.size()); - for (::llvm::memprof::FrameId Id : CS) - Frames.push_back(IdToFrameCallback(Id)); - } - return Frames; - }; + const ::llvm::memprof::MemProfRecord WantRecord = + IndexedMR.toMemProfRecord(CSIdConv); + ASSERT_EQ(CSIdConv.LastUnmappedFrameId, std::nullopt) + << "could not map frame id: " << *CSIdConv.LastUnmappedFrameId; + ASSERT_EQ(CSIdConv.LastUnmappedCSId, std::nullopt) + << "could not map call stack id: " << *CSIdConv.LastUnmappedCSId; + EXPECT_THAT(WantRecord, EqualsRecord(Record)); +} + +TEST_F(InstrProfTest, test_memprof_v2_partial_schema) { + const MemInfoBlock MIB = makePartialMIB(); + + Writer.setMemProfVersionRequested(memprof::Version2); + Writer.setMemProfFullSchema(false); + + ASSERT_THAT_ERROR(Writer.mergeProfileKind(InstrProfKind::MemProf), + Succeeded()); + + const IndexedMemProfRecord IndexedMR = makeRecordV2( + /*AllocFrames=*/{0x111, 0x222}, + /*CallSiteFrames=*/{0x333}, MIB); + const FrameIdMapTy IdToFrameMap = getFrameMapping(); + const auto CSIdToCallStackMap = getCallStackMapping(); + for (const auto &I : IdToFrameMap) { + Writer.addMemProfFrame(I.first, I.getSecond(), Err); + } + for (const auto &I : CSIdToCallStackMap) { + Writer.addMemProfCallStack(I.first, I.getSecond(), Err); + } + Writer.addMemProfRecord(/*Id=*/0x9999, IndexedMR); + + auto Profile = Writer.writeBuffer(); + readProfile(std::move(Profile)); + + auto RecordOr = Reader->getMemProfRecord(0x9999); + ASSERT_THAT_ERROR(RecordOr.takeError(), Succeeded()); + const memprof::MemProfRecord &Record = RecordOr.get(); + + CallStackIdConverter CSIdConv(IdToFrameMap, CSIdToCallStackMap); const ::llvm::memprof::MemProfRecord WantRecord = - IndexedMR.toMemProfRecord(CSIdToCallStackCallback); - ASSERT_EQ(LastUnmappedFrameId, std::nullopt) - << "could not map frame id: " << *LastUnmappedFrameId; - ASSERT_EQ(LastUnmappedCSId, std::nullopt) - << "could not map call stack id: " << *LastUnmappedCSId; + IndexedMR.toMemProfRecord(CSIdConv); + ASSERT_EQ(CSIdConv.LastUnmappedFrameId, std::nullopt) + << "could not map frame id: " << *CSIdConv.LastUnmappedFrameId; + ASSERT_EQ(CSIdConv.LastUnmappedCSId, std::nullopt) + << "could not map call stack id: " << *CSIdConv.LastUnmappedCSId; EXPECT_THAT(WantRecord, EqualsRecord(Record)); } -- GitLab From b9f2c16b50f68c978e90190f46a7c0db3f39e98c Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 24 Apr 2024 16:25:45 -0700 Subject: [PATCH 039/733] [MC] Rename temporary symbols of empty name to ".L0 " (#89693) Temporary symbols generated for .eh_frame and .debug_line have an empty name, which appear in .symtab in the presence of RISC-V style linker relaxation and will not be discarded by ld/objcopy --discard-locals (-X). In contrast, GNU assembler's riscv port assigns a fake name ".L0 " (with a trailing space) to these symbols so that will be discarded by ld/objcopy --discard-locals. This patch matches the GNU behavior. Since Clang's RISC-V targets pass -X to ld, and GNU ld defaults to -X for RISC-V targets, these ".L0 " symbols will be discarded after linking by default, as expected by users. The llvm-symbolizer special case for RISC-V `SF_FormatSpecific` symbols https://reviews.llvm.org/D98669 needs to be adjusted. Note: `"":` in assembly currently crashes. --- bolt/test/RISCV/unnamed-sym-no-entry.c | 2 +- lld/test/ELF/mips-eh_frame-pic.s | 4 +-- llvm/include/llvm/Object/ELFObjectFile.h | 5 ++- llvm/lib/MC/ELFObjectWriter.cpp | 6 ++++ llvm/test/CodeGen/RISCV/fixups-diff.ll | 2 +- .../LoongArch/dwarf-loongarch-relocs.ll | 18 +++++------ .../DebugInfo/RISCV/dwarf-riscv-relocs.ll | 12 +++---- .../test/DebugInfo/RISCV/relax-debug-frame.ll | 10 +++--- ...name-symbol.s => riscv-temporary-symbol.s} | 5 +-- .../JITLink/RISCV/anonymous_symbol.s | 2 +- llvm/test/MC/ELF/RISCV/gen-dwarf.s | 26 +++++++-------- llvm/test/MC/RISCV/cfi-advance.s | 32 +++++++++++++++---- llvm/test/MC/RISCV/fde-reloc.s | 2 +- llvm/test/MC/RISCV/scoped-relaxation.s | 6 ++-- 14 files changed, 79 insertions(+), 53 deletions(-) rename llvm/test/DebugInfo/Symbolize/ELF/{riscv-empty-name-symbol.s => riscv-temporary-symbol.s} (71%) diff --git a/bolt/test/RISCV/unnamed-sym-no-entry.c b/bolt/test/RISCV/unnamed-sym-no-entry.c index 605bbc00aeec..b4173506b213 100644 --- a/bolt/test/RISCV/unnamed-sym-no-entry.c +++ b/bolt/test/RISCV/unnamed-sym-no-entry.c @@ -8,7 +8,7 @@ /// Verify that the binary indeed contains an unnamed symbol at _start // RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=CHECK-ELF // CHECK-ELF-DAG: [[#%x,START:]] {{.*}} FUNC GLOBAL DEFAULT [[#%d,SECTION:]] _start{{$}} -// CHECK-ELF-DAG: [[#%x,START]] {{.*}} NOTYPE LOCAL DEFAULT [[#SECTION]] {{$}} +// CHECK-ELF-DAG: [[#%x,START]] {{.*}} NOTYPE LOCAL DEFAULT [[#SECTION]] .L0 {{$}} /// Verify that BOLT did not create an extra entry point for the unnamed symbol // RUN: llvm-bolt -o %t.bolt %t --print-cfg | FileCheck %s diff --git a/lld/test/ELF/mips-eh_frame-pic.s b/lld/test/ELF/mips-eh_frame-pic.s index a84c36b0e5ec..c04dbdf57b08 100644 --- a/lld/test/ELF/mips-eh_frame-pic.s +++ b/lld/test/ELF/mips-eh_frame-pic.s @@ -36,8 +36,8 @@ # RELOCS: .rel{{a?}}.eh_frame { # ABS32-RELOCS-NEXT: 0x1C R_MIPS_32 .text # ABS64-RELOCS-NEXT: 0x1C R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE .text -# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE -# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 +# PIC64-RELOCS-NEXT: 0x1C R_MIPS_PC32/R_MIPS_NONE/R_MIPS_NONE .L0 +# PIC32-RELOCS-NEXT: 0x1C R_MIPS_PC32 .L0 # RELOCS-NEXT: } # ABS64-EH-FRAME: Augmentation data: 0C diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 1d457be93741..4494d9b96189 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -801,9 +801,8 @@ Expected ELFObjectFile::getSymbolFlags(DataRefImpl Sym) const { } else if (EF.getHeader().e_machine == ELF::EM_RISCV) { if (Expected NameOrErr = getSymbolName(Sym)) { StringRef Name = *NameOrErr; - // Mark empty name symbols (used for label differences) and mapping - // symbols. - if (Name.empty() || Name.starts_with("$d") || Name.starts_with("$x")) + // Mark fake labels (used for label differences) and mapping symbols. + if (Name == ".L0 " || Name.starts_with("$d") || Name.starts_with("$x")) Result |= SymbolRef::SF_FormatSpecific; } else { // TODO: Actually report errors helpfully. diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 005521bad6e0..b8ef2654ed6e 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -725,7 +725,13 @@ void ELFWriter::computeSymbolTable( HasLargeSectionIndex = true; } + // Temporary symbols generated for certain assembler features (.eh_frame, + // .debug_line) of an empty name may be referenced by relocations due to + // linker relaxation. Rename them to ".L0 " to match the gas fake label name + // and allow ld/objcopy --discard-locals to discard such symbols. StringRef Name = Symbol.getName(); + if (Name.empty()) + Name = ".L0 "; // Sections have their own string table if (Symbol.getType() != ELF::STT_SECTION) { diff --git a/llvm/test/CodeGen/RISCV/fixups-diff.ll b/llvm/test/CodeGen/RISCV/fixups-diff.ll index cc1c87b1fe37..84a7d18ed150 100644 --- a/llvm/test/CodeGen/RISCV/fixups-diff.ll +++ b/llvm/test/CodeGen/RISCV/fixups-diff.ll @@ -27,7 +27,7 @@ entry: ; CHECK: } ; CHECK: Section {{.*}} .rela.eh_frame { -; CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 +; CHECK-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 ; CHECK-NEXT: } !llvm.dbg.cu = !{!0} diff --git a/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll b/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll index d6a1d8d6e136..d28836d56037 100644 --- a/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll +++ b/llvm/test/DebugInfo/LoongArch/dwarf-loongarch-relocs.ll @@ -18,21 +18,21 @@ ; RELOCS-BOTH: Section ({{.*}}) .rela.debug_frame { ; RELOCS-NORL-NEXT: 0x1C R_LARCH_32 .debug_frame 0x0 ; RELOCS-NORL-NEXT: 0x20 R_LARCH_64 .text 0x0 -; RELOCS-ENRL-NEXT: 0x1C R_LARCH_32 0x0 -; RELOCS-ENRL-NEXT: 0x20 R_LARCH_64 0x0 -; RELOCS-ENRL-NEXT: 0x28 R_LARCH_ADD64 0x0 -; RELOCS-ENRL-NEXT: 0x28 R_LARCH_SUB64 0x0 -; RELOCS-ENRL-NEXT: 0x3F R_LARCH_ADD6 0x0 -; RELOCS-ENRL-NEXT: 0x3F R_LARCH_SUB6 0x0 +; RELOCS-ENRL-NEXT: 0x1C R_LARCH_32 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x20 R_LARCH_64 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x28 R_LARCH_ADD64 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x28 R_LARCH_SUB64 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x3F R_LARCH_ADD6 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x3F R_LARCH_SUB6 .L0 0x0 ; RELOCS-BOTH-NEXT: } ; RELOCS-BOTH: Section ({{.*}}) .rela.debug_line { ; RELOCS-BOTH-NEXT: 0x22 R_LARCH_32 .debug_line_str 0x0 ; RELOCS-BOTH-NEXT: 0x31 R_LARCH_32 .debug_line_str 0x2 ; RELOCS-BOTH-NEXT: 0x46 R_LARCH_32 .debug_line_str 0x1B ; RELOCS-NORL-NEXT: 0x4F R_LARCH_64 .text 0x0 -; RELOCS-ENRL-NEXT: 0x4F R_LARCH_64 0x0 -; RELOCS-ENRL-NEXT: 0x5F R_LARCH_ADD16 0x0 -; RELOCS-ENRL-NEXT: 0x5F R_LARCH_SUB16 0x0 +; RELOCS-ENRL-NEXT: 0x4F R_LARCH_64 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x5F R_LARCH_ADD16 .L0 0x0 +; RELOCS-ENRL-NEXT: 0x5F R_LARCH_SUB16 .L0 0x0 ; RELOCS-BOTH-NEXT: } ; RELOCS-BOTH-NEXT: ] diff --git a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll index e5de1713f4e0..99594b5e01e9 100644 --- a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll +++ b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll @@ -6,14 +6,14 @@ ; Check that we actually have relocations, otherwise this is kind of pointless. ; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_info { -; READOBJ-RELOCS: 0x1B R_RISCV_ADD32 0x0 -; READOBJ-RELOCS-NEXT: 0x1B R_RISCV_SUB32 0x0 +; READOBJ-RELOCS: 0x1B R_RISCV_ADD32 .L0 0x0 +; READOBJ-RELOCS-NEXT: 0x1B R_RISCV_SUB32 .L0 0x0 ; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_frame { -; READOBJ-RELOCS: 0x20 R_RISCV_ADD32 0x0 -; READOBJ-RELOCS-NEXT: 0x20 R_RISCV_SUB32 0x0 +; READOBJ-RELOCS: 0x20 R_RISCV_ADD32 .L0 0x0 +; READOBJ-RELOCS-NEXT: 0x20 R_RISCV_SUB32 .L0 0x0 ; READOBJ-RELOCS: Section ({{.*}}) .rela.debug_line { -; READOBJ-RELOCS: 0x5A R_RISCV_ADD16 0x0 -; READOBJ-RELOCS-NEXT: 0x5A R_RISCV_SUB16 0x0 +; READOBJ-RELOCS: 0x5A R_RISCV_ADD16 .L0 0x0 +; READOBJ-RELOCS-NEXT: 0x5A R_RISCV_SUB16 .L0 0x0 ; Check that we can print the source, even with relocations. ; OBJDUMP-SOURCE: Disassembly of section .text: diff --git a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll index f655a7c0a7ef..ffef0ec23406 100644 --- a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll +++ b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll @@ -4,11 +4,11 @@ ; RUN: | FileCheck -check-prefix=RELAX-DWARFDUMP %s ; ; RELAX: Section ({{.*}}) .rela.eh_frame { -; RELAX-NEXT: 0x1C R_RISCV_32_PCREL 0x0 -; RELAX-NEXT: 0x30 R_RISCV_32_PCREL 0x0 -; RELAX-NEXT: 0x44 R_RISCV_32_PCREL 0x0 -; RELAX-NEXT: 0x48 R_RISCV_ADD32 0x0 -; RELAX-NEXT: 0x48 R_RISCV_SUB32 0x0 +; RELAX-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 +; RELAX-NEXT: 0x30 R_RISCV_32_PCREL .L0 0x0 +; RELAX-NEXT: 0x44 R_RISCV_32_PCREL .L0 0x0 +; RELAX-NEXT: 0x48 R_RISCV_ADD32 .L0 0x0 +; RELAX-NEXT: 0x48 R_RISCV_SUB32 .L0 0x0 ; RELAX-NEXT: } ; RELAX-DWARFDUMP-NOT: error: failed to compute relocation diff --git a/llvm/test/DebugInfo/Symbolize/ELF/riscv-empty-name-symbol.s b/llvm/test/DebugInfo/Symbolize/ELF/riscv-temporary-symbol.s similarity index 71% rename from llvm/test/DebugInfo/Symbolize/ELF/riscv-empty-name-symbol.s rename to llvm/test/DebugInfo/Symbolize/ELF/riscv-temporary-symbol.s index 1e0fa8a30618..0b54f104ab95 100644 --- a/llvm/test/DebugInfo/Symbolize/ELF/riscv-empty-name-symbol.s +++ b/llvm/test/DebugInfo/Symbolize/ELF/riscv-temporary-symbol.s @@ -1,10 +1,11 @@ # REQUIRES: riscv-registered-target -## Ignore empty name symbols. +## Ignore .L0 symbols that are generated by LLVM integrated assembler and GNU +## assembler for .debug_line/.eh_frame related assembler directives. # RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t # RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYM -# SYM: 0000000000000004 0 NOTYPE LOCAL DEFAULT [[#]] {{$}} +# SYM: 0000000000000004 0 NOTYPE LOCAL DEFAULT [[#]] .L0 {{$}} # SYM: 0000000000000000 0 NOTYPE GLOBAL DEFAULT [[#]] foo ## Make sure we test at an address larger than or equal to an empty name symbol. diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s b/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s index a5038022dfe0..e7114e4d643c 100644 --- a/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/anonymous_symbol.s @@ -7,7 +7,7 @@ # the section start and section end. So that by relocating these symbol, the section length # can be calculated. # -# CHECK: Creating defined graph symbol for ELF symbol "" +# CHECK: Creating defined graph symbol for ELF symbol ".L0 " # CHECK: Creating defined graph symbol for ELF symbol "main" .text .globl main diff --git a/llvm/test/MC/ELF/RISCV/gen-dwarf.s b/llvm/test/MC/ELF/RISCV/gen-dwarf.s index 342ed1cc0e7e..34d02f5da44f 100644 --- a/llvm/test/MC/ELF/RISCV/gen-dwarf.s +++ b/llvm/test/MC/ELF/RISCV/gen-dwarf.s @@ -40,28 +40,28 @@ # CHECK-NEXT: 0x00000020: [DW_RLE_end_of_list ] # RELOC: Section ([[#]]) .rela.eh_frame { -# RELOC-NEXT: 0x1C R_RISCV_32_PCREL 0x0 -# RELOC-NEXT: 0x20 R_RISCV_ADD32 0x0 -# RELOC-NEXT: 0x20 R_RISCV_SUB32 0x0 -# RELOC-NEXT: 0x25 R_RISCV_SET6 0x0 -# RELOC-NEXT: 0x25 R_RISCV_SUB6 0x0 -# RELOC-NEXT: 0x34 R_RISCV_32_PCREL 0x0 +# RELOC-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 +# RELOC-NEXT: 0x20 R_RISCV_ADD32 .L0 0x0 +# RELOC-NEXT: 0x20 R_RISCV_SUB32 .L0 0x0 +# RELOC-NEXT: 0x25 R_RISCV_SET6 .L0 0x0 +# RELOC-NEXT: 0x25 R_RISCV_SUB6 .L0 0x0 +# RELOC-NEXT: 0x34 R_RISCV_32_PCREL .L0 0x0 # RELOC-NEXT: } # RELOC: Section ([[#]]) .rela.debug_rnglists { # RELOC-NEXT: 0xD R_RISCV_64 .text.foo 0x0 -# RELOC-NEXT: 0x15 R_RISCV_SET_ULEB128 0x0 +# RELOC-NEXT: 0x15 R_RISCV_SET_ULEB128 .L0 0x0 # RELOC-NEXT: 0x15 R_RISCV_SUB_ULEB128 .text.foo 0x0 # RELOC-NEXT: 0x17 R_RISCV_64 .text.bar 0x0 # RELOC-NEXT: } # RELOC: Section ([[#]]) .rela.debug_line { -# RELOC: R_RISCV_ADD16 0x0 -# RELOC-NEXT: R_RISCV_SUB16 0x0 -# RELOC-NEXT: R_RISCV_ADD16 0x0 -# RELOC-NEXT: R_RISCV_SUB16 0x0 -# RELOC-NEXT: R_RISCV_ADD16 0x0 -# RELOC-NEXT: R_RISCV_SUB16 0x0 +# RELOC: R_RISCV_ADD16 .L0 0x0 +# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0 +# RELOC-NEXT: R_RISCV_ADD16 .L0 0x0 +# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0 +# RELOC-NEXT: R_RISCV_ADD16 .L0 0x0 +# RELOC-NEXT: R_RISCV_SUB16 .L0 0x0 # RELOC: } # RELOC: Hex dump of section '.eh_frame': diff --git a/llvm/test/MC/RISCV/cfi-advance.s b/llvm/test/MC/RISCV/cfi-advance.s index c4af390be757..b99af38f553a 100644 --- a/llvm/test/MC/RISCV/cfi-advance.s +++ b/llvm/test/MC/RISCV/cfi-advance.s @@ -1,13 +1,27 @@ # RUN: llvm-mc -filetype=obj -triple riscv32 %s -o %t.o -# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=CHECK %s +# RUN: llvm-readelf -sr %t.o | FileCheck %s # RUN: llvm-dwarfdump --debug-frame %t.o 2>&1 \ # RUN: | FileCheck -check-prefix=CHECK-DWARFDUMP %s -# CHECK: .rela.eh_frame { -# CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 -# CHECK-NEXT: 0x35 R_RISCV_SET6 0x0 -# CHECK-NEXT: 0x35 R_RISCV_SUB6 0x0 -# CHECK-NEXT: } + +# CHECK: Relocation section '.rela.text1' at offset {{.*}} contains 1 entries: +# CHECK-NEXT: Offset Info Type Sym. Value Symbol's Name + Addend +# CHECK-NEXT: 00000000 00000313 R_RISCV_CALL_PLT 00000004 .L0 + 0 +# CHECK-EMPTY: +# CHECK-NEXT: Relocation section '.rela.eh_frame' at offset {{.*}} contains 3 entries: +# CHECK: Offset Info Type Sym. Value Symbol's Name + Addend +# CHECK-NEXT: 0000001c 00000139 R_RISCV_32_PCREL 00000000 .L0 + 0 +# CHECK-NEXT: 00000035 00000b35 R_RISCV_SET6 00010178 .L0 + 0 +# CHECK-NEXT: 00000035 00000934 R_RISCV_SUB6 0001016e .L0 + 0 +# CHECK-EMPTY: +# CHECK: Symbol table '.symtab' contains 15 entries: +# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name +# CHECK-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND +# CHECK-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}} +# CHECK: 3: 00000004 0 NOTYPE LOCAL DEFAULT 2 .L0{{$}} +# CHECK: 9: 0001016e 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}} +# CHECK: 11: 00010178 0 NOTYPE LOCAL DEFAULT 2 .L0 {{$}} + # CHECK-DWARFDUMP: DW_CFA_advance_loc1: 104 # CHECK-DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8 # CHECK-DWARFDUMP-NEXT: DW_CFA_advance_loc2: 259 @@ -23,6 +37,9 @@ test: .cfi_startproc nop +## This looks similar to fake label names ".L0 ". Even if this is ".L0 ", +## the assembler will not conflate it with fake labels. +.L0: .zero 100, 0x90 .cfi_def_cfa_offset 8 nop @@ -36,3 +53,6 @@ test: .cfi_def_cfa_offset 8 nop .cfi_endproc + +.section .text1,"ax" +call .L0 diff --git a/llvm/test/MC/RISCV/fde-reloc.s b/llvm/test/MC/RISCV/fde-reloc.s index 1db8929e0747..81ec426c8b61 100644 --- a/llvm/test/MC/RISCV/fde-reloc.s +++ b/llvm/test/MC/RISCV/fde-reloc.s @@ -12,7 +12,7 @@ func: .cfi_endproc # CHECK: Section (4) .rela.eh_frame { -# CHECK-NEXT: 0x1C R_RISCV_32_PCREL 0x0 +# CHECK-NEXT: 0x1C R_RISCV_32_PCREL .L0 0x0 # CHECK-NEXT: } # CHECK: Hex dump of section '.eh_frame': # CHECK-NEXT: 0x00000000 10000000 00000000 017a5200 017c0101 diff --git a/llvm/test/MC/RISCV/scoped-relaxation.s b/llvm/test/MC/RISCV/scoped-relaxation.s index 0b797ee5aca5..56394fd80532 100644 --- a/llvm/test/MC/RISCV/scoped-relaxation.s +++ b/llvm/test/MC/RISCV/scoped-relaxation.s @@ -9,7 +9,7 @@ .dword function - . # CHECK: 0x0 R_RISCV_ADD64 function 0x0 -# CHECK-NEXT: 0x0 R_RISCV_SUB64 0x0 +# CHECK-NEXT: 0x0 R_RISCV_SUB64 .L0 0x0 # Relaxed reference, this will resolve to a pair of `RISCV_ADD64` and # `RISCV_SUB64` relocation. @@ -19,7 +19,7 @@ .option pop # CHECK: 0x8 R_RISCV_ADD64 function 0x0 -# CHECK-NEXT: 0x8 R_RISCV_SUB64 0x0 +# CHECK-NEXT: 0x8 R_RISCV_SUB64 .L0 0x0 # Unrelaxed reference, this will resolve to a pair of `RISCV_ADD64` and # `RISCV_SUB64` relocation due to relaxation being sticky to the file. @@ -29,6 +29,6 @@ .option pop # CHECK: 0x10 R_RISCV_ADD64 function 0x0 -# CHECK-NEXT: 0x10 R_RISCV_SUB64 0x0 +# CHECK-NEXT: 0x10 R_RISCV_SUB64 .L0 0x0 # CHECK: } -- GitLab From d5308949cf884d8e4b971d51a8b4f73584c4adec Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Wed, 24 Apr 2024 20:31:18 -0400 Subject: [PATCH 040/733] [clang][Sema] Preserve the initializer of invalid VarDecls (#88645) Fixes https://github.com/clangd/clangd/issues/1821 --- clang/lib/Sema/JumpDiagnostics.cpp | 3 ++- clang/lib/Sema/SemaDecl.cpp | 23 +++++++++++++++++------ clang/test/AST/ast-dump-recovery.cpp | 8 ++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index ce6211c23218..8af36d5c24e3 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -180,7 +180,8 @@ static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) { } const Expr *Init = VD->getInit(); - if (S.Context.getLangOpts().CPlusPlus && VD->hasLocalStorage() && Init) { + if (S.Context.getLangOpts().CPlusPlus && VD->hasLocalStorage() && Init && + !Init->containsErrors()) { // C++11 [stmt.dcl]p3: // A program that jumps from a point where a variable with automatic // storage duration is not in scope to a point where it is in scope diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 378615497b13..e0745fe9a453 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -13502,16 +13502,18 @@ void Sema::checkNonTrivialCUnion(QualType QT, SourceLocation Loc, void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // If there is no declaration, there was an error parsing it. Just ignore // the initializer. - if (!RealDecl || RealDecl->isInvalidDecl()) { + if (!RealDecl) { CorrectDelayedTyposInExpr(Init, dyn_cast_or_null(RealDecl)); return; } - if (CXXMethodDecl *Method = dyn_cast(RealDecl)) { - // Pure-specifiers are handled in ActOnPureSpecifier. - Diag(Method->getLocation(), diag::err_member_function_initialization) - << Method->getDeclName() << Init->getSourceRange(); - Method->setInvalidDecl(); + if (auto *Method = dyn_cast(RealDecl)) { + if (!Method->isInvalidDecl()) { + // Pure-specifiers are handled in ActOnPureSpecifier. + Diag(Method->getLocation(), diag::err_member_function_initialization) + << Method->getDeclName() << Init->getSourceRange(); + Method->setInvalidDecl(); + } return; } @@ -13523,6 +13525,15 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { return; } + if (VDecl->isInvalidDecl()) { + CorrectDelayedTyposInExpr(Init, VDecl); + ExprResult Recovery = + CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), {Init}); + if (Expr *E = Recovery.get()) + VDecl->setInit(E); + return; + } + // WebAssembly tables can't be used to initialise a variable. if (Init && !Init->getType().isNull() && Init->getType()->isWebAssemblyTableType()) { diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp index cfb013585ad7..77527743fe85 100644 --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -413,6 +413,14 @@ void RecoveryExprForInvalidDecls(Unknown InvalidDecl) { // CHECK-NEXT: `-RecoveryExpr {{.*}} '' } +void InitializerOfInvalidDecl() { + int ValidDecl; + Unkown InvalidDecl = ValidDecl; + // CHECK: VarDecl {{.*}} invalid InvalidDecl + // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors + // CHECK-NEXT: `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl' +} + void RecoverToAnInvalidDecl() { Unknown* foo; // invalid decl goo; // the typo was correct to the invalid foo. -- GitLab From a35d7d7d124172632a9a108f76deba647f4da863 Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Wed, 24 Apr 2024 04:10:35 -0400 Subject: [PATCH 041/733] [AArch64][SelectionDAG] Correct the shift amounts bound Accord D152827, when the shift amounts is 4 or less, they are cheap as a move. --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 4 ++-- llvm/test/CodeGen/AArch64/mul_pow2.ll | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 892b5853e00e..3d2fa3953976 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -17610,8 +17610,8 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG, APInt CVNMinus1 = CVN - 1; unsigned ShiftM1 = CVMMinus1.logBase2(); unsigned ShiftN1 = CVNMinus1.logBase2(); - // LSLFast implicate that Shifts <= 3 places are fast - if (ShiftM1 <= 3 && ShiftN1 <= 3) { + // ALULSLFast implicate that Shifts <= 4 places are fast + if (ShiftM1 <= 4 && ShiftN1 <= 4) { SDValue MVal = Add(Shl(N0, ShiftM1), N0); return Add(Shl(MVal, ShiftN1), MVal); } diff --git a/llvm/test/CodeGen/AArch64/mul_pow2.ll b/llvm/test/CodeGen/AArch64/mul_pow2.ll index 90e560af4465..9f8ba8bc6bdc 100644 --- a/llvm/test/CodeGen/AArch64/mul_pow2.ll +++ b/llvm/test/CodeGen/AArch64/mul_pow2.ll @@ -545,12 +545,11 @@ define i32 @test45(i32 %x) { ret i32 %mul } -; Negative test: The shift amount 4 larger than 3 define i32 @test85_fast_shift(i32 %x) "target-features"="+alu-lsl-fast" { ; CHECK-LABEL: test85_fast_shift: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #85 // =0x55 -; CHECK-NEXT: mul w0, w0, w8 +; CHECK-NEXT: add w8, w0, w0, lsl #2 +; CHECK-NEXT: add w0, w8, w8, lsl #4 ; CHECK-NEXT: ret ; ; GISEL-LABEL: test85_fast_shift: @@ -563,7 +562,7 @@ define i32 @test85_fast_shift(i32 %x) "target-features"="+alu-lsl-fast" { ret i32 %mul } -; Negative test: The shift amount 5 larger than 3 +; Negative test: The shift amount 5 larger than 4 define i32 @test297_fast_shift(i32 %x) "target-features"="+alu-lsl-fast" { ; CHECK-LABEL: test297_fast_shift: ; CHECK: // %bb.0: -- GitLab From a6bdd6df23613c3ee5b3d7c31b1cf1fb78403a15 Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Sun, 21 Apr 2024 01:22:13 -0400 Subject: [PATCH 042/733] [AArch64][SelectionDAG] Lower multiplication by a constant to shl+add+shl+add Change the costmodel to lower a = b * C where C = (1 + 2^m) * 2^n + 1 to add w8, w0, w0, lsl #m add w0, w0, w8, lsl #n Note: The latency of add can vary depending on the shirt amount They are cheap as a move when the shift amounts is 4 or less. Fix part of https://github.com/llvm/llvm-project/issues/89430 --- .../Target/AArch64/AArch64ISelLowering.cpp | 35 +++++++++++- llvm/test/CodeGen/AArch64/mul_pow2.ll | 57 ++++++++++++++++++- 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 3d2fa3953976..223898e9d634 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -17585,12 +17585,32 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG, return false; }; + // Can the const C be decomposed into (2^M + 1) * 2^N + 1), eg: + // C = 11 is equal to (1+4)*2+1, we don't decompose it into (1+2)*4-1 as + // the (2^N - 1) can't be execused via a single instruction. + auto isPowPlusPlusOneConst = [](APInt C, APInt &M, APInt &N) { + APInt CVMinus1 = C - 1; + if (CVMinus1.isNegative()) + return false; + unsigned TrailingZeroes = CVMinus1.countr_zero(); + APInt SCVMinus1 = CVMinus1.ashr(TrailingZeroes) - 1; + if (SCVMinus1.isPowerOf2()) { + unsigned BitWidth = SCVMinus1.getBitWidth(); + M = APInt(BitWidth, SCVMinus1.logBase2()); + N = APInt(BitWidth, TrailingZeroes); + return true; + } + return false; + }; + if (ConstValue.isNonNegative()) { // (mul x, (2^N + 1) * 2^M) => (shl (add (shl x, N), x), M) // (mul x, 2^N - 1) => (sub (shl x, N), x) // (mul x, (2^(N-M) - 1) * 2^M) => (sub (shl x, N), (shl x, M)) // (mul x, (2^M + 1) * (2^N + 1)) // => MV = (add (shl x, M), x); (add (shl MV, N), MV) + // (mul x, (2^M + 1) * 2^N + 1)) + // => MV = add (shl x, M), x); add (shl MV, N), x) APInt SCVMinus1 = ShiftedConstValue - 1; APInt SCVPlus1 = ShiftedConstValue + 1; APInt CVPlus1 = ConstValue + 1; @@ -17604,8 +17624,9 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG, } else if (SCVPlus1.isPowerOf2()) { ShiftAmt = SCVPlus1.logBase2() + TrailingZeroes; return Sub(Shl(N0, ShiftAmt), Shl(N0, TrailingZeroes)); - } else if (Subtarget->hasALULSLFast() && - isPowPlusPlusConst(ConstValue, CVM, CVN)) { + } + if (Subtarget->hasALULSLFast() && + isPowPlusPlusConst(ConstValue, CVM, CVN)) { APInt CVMMinus1 = CVM - 1; APInt CVNMinus1 = CVN - 1; unsigned ShiftM1 = CVMMinus1.logBase2(); @@ -17616,6 +17637,16 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG, return Add(Shl(MVal, ShiftN1), MVal); } } + if (Subtarget->hasALULSLFast() && + isPowPlusPlusOneConst(ConstValue, CVM, CVN)) { + unsigned ShiftM = CVM.getZExtValue(); + unsigned ShiftN = CVN.getZExtValue(); + // ALULSLFast implicate that Shifts <= 4 places are fast + if (ShiftM <= 4 && ShiftN <= 4) { + SDValue MVal = Add(Shl(N0, CVM.getZExtValue()), N0); + return Add(Shl(MVal, CVN.getZExtValue()), N0); + } + } } else { // (mul x, -(2^N - 1)) => (sub x, (shl x, N)) // (mul x, -(2^N + 1)) => - (add (shl x, N), x) diff --git a/llvm/test/CodeGen/AArch64/mul_pow2.ll b/llvm/test/CodeGen/AArch64/mul_pow2.ll index 9f8ba8bc6bdc..0c9ea51ba367 100644 --- a/llvm/test/CodeGen/AArch64/mul_pow2.ll +++ b/llvm/test/CodeGen/AArch64/mul_pow2.ll @@ -410,6 +410,23 @@ define i32 @test11(i32 %x) { ret i32 %mul } +define i32 @test11_fast_shift(i32 %x) "target-features"="+alu-lsl-fast" { +; CHECK-LABEL: test11_fast_shift: +; CHECK: // %bb.0: +; CHECK-NEXT: add w8, w0, w0, lsl #2 +; CHECK-NEXT: add w0, w0, w8, lsl #1 +; CHECK-NEXT: ret +; +; GISEL-LABEL: test11_fast_shift: +; GISEL: // %bb.0: +; GISEL-NEXT: mov w8, #11 // =0xb +; GISEL-NEXT: mul w0, w0, w8 +; GISEL-NEXT: ret + + %mul = mul nsw i32 %x, 11 ; 11 = (((1<<2) + 1) << 1) + 1 + ret i32 %mul +} + define i32 @test12(i32 %x) { ; CHECK-LABEL: test12: ; CHECK: // %bb.0: @@ -545,6 +562,24 @@ define i32 @test45(i32 %x) { ret i32 %mul } +; Negative test: The shift number 5 is out of bound +define i32 @test67_fast_shift(i32 %x) "target-features"="+alu-lsl-fast" { +; CHECK-LABEL: test67_fast_shift: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #67 // =0x43 +; CHECK-NEXT: mul w0, w0, w8 +; CHECK-NEXT: ret +; +; GISEL-LABEL: test67_fast_shift: +; GISEL: // %bb.0: +; GISEL-NEXT: mov w8, #67 // =0x43 +; GISEL-NEXT: mul w0, w0, w8 +; GISEL-NEXT: ret + + %mul = mul nsw i32 %x, 67 ; 67 = (((1<<5) + 1) << 1) + 1 + ret i32 %mul +} + define i32 @test85_fast_shift(i32 %x) "target-features"="+alu-lsl-fast" { ; CHECK-LABEL: test85_fast_shift: ; CHECK: // %bb.0: @@ -562,6 +597,24 @@ define i32 @test85_fast_shift(i32 %x) "target-features"="+alu-lsl-fast" { ret i32 %mul } +; Negative test: The shift number 5 is out of bound +define i32 @test97_fast_shift(i32 %x) "target-features"="+alu-lsl-fast" { +; CHECK-LABEL: test97_fast_shift: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #97 // =0x61 +; CHECK-NEXT: mul w0, w0, w8 +; CHECK-NEXT: ret +; +; GISEL-LABEL: test97_fast_shift: +; GISEL: // %bb.0: +; GISEL-NEXT: mov w8, #97 // =0x61 +; GISEL-NEXT: mul w0, w0, w8 +; GISEL-NEXT: ret + + %mul = mul nsw i32 %x, 97 ; 97 = ((2 + 1) << 5) + 1 + ret i32 %mul +} + ; Negative test: The shift amount 5 larger than 4 define i32 @test297_fast_shift(i32 %x) "target-features"="+alu-lsl-fast" { ; CHECK-LABEL: test297_fast_shift: @@ -857,9 +910,9 @@ define <4 x i32> @muladd_demand_commute(<4 x i32> %x, <4 x i32> %y) { ; ; GISEL-LABEL: muladd_demand_commute: ; GISEL: // %bb.0: -; GISEL-NEXT: adrp x8, .LCPI49_0 +; GISEL-NEXT: adrp x8, .LCPI52_0 ; GISEL-NEXT: movi v3.4s, #1, msl #16 -; GISEL-NEXT: ldr q2, [x8, :lo12:.LCPI49_0] +; GISEL-NEXT: ldr q2, [x8, :lo12:.LCPI52_0] ; GISEL-NEXT: mla v1.4s, v0.4s, v2.4s ; GISEL-NEXT: and v0.16b, v1.16b, v3.16b ; GISEL-NEXT: ret -- GitLab From 1d77eb49a4278521180146c977995bf0356f69c3 Mon Sep 17 00:00:00 2001 From: Chen Zheng Date: Wed, 24 Apr 2024 20:54:45 -0400 Subject: [PATCH 043/733] Revert "[PPC] [NFC] add testcase for more store forwarding" This reverts commit 29c7d1a60c9d45e82f08cd7487178846ed5f9c6d. The store forwarding patch https://github.com/llvm/llvm-project/pull/87465 is closed. --- llvm/test/CodeGen/PowerPC/legalize-vaarg.ll | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/llvm/test/CodeGen/PowerPC/legalize-vaarg.ll b/llvm/test/CodeGen/PowerPC/legalize-vaarg.ll index 8980049969da..b7f8b8af2472 100644 --- a/llvm/test/CodeGen/PowerPC/legalize-vaarg.ll +++ b/llvm/test/CodeGen/PowerPC/legalize-vaarg.ll @@ -1,7 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ;RUN: llc < %s --mtriple=powerpc64-unknown-linux-gnu -mattr=+altivec | FileCheck %s -check-prefix=BE ;RUN: llc < %s --mtriple=powerpc64le-unknown-linux-gnu -mattr=+altivec | FileCheck %s -check-prefix=LE -;RUN: llc < %s --mtriple=powerpc64-unknown-linux-gnu -mattr=+altivec -ppc-gather-alias-max-depth=0 | FileCheck %s -check-prefix=FORWARD define <8 x i32> @test_large_vec_vaarg(i32 %n, ...) { ; BE-LABEL: test_large_vec_vaarg: @@ -36,22 +35,6 @@ define <8 x i32> @test_large_vec_vaarg(i32 %n, ...) { ; LE-NEXT: lxvd2x 0, 0, 3 ; LE-NEXT: xxswapd 35, 0 ; LE-NEXT: blr -; -; FORWARD-LABEL: test_large_vec_vaarg: -; FORWARD: # %bb.0: -; FORWARD-NEXT: ld 3, -8(1) -; FORWARD-NEXT: addi 3, 3, 15 -; FORWARD-NEXT: rldicr 3, 3, 0, 59 -; FORWARD-NEXT: addi 4, 3, 16 -; FORWARD-NEXT: std 4, -8(1) -; FORWARD-NEXT: ld 4, -8(1) -; FORWARD-NEXT: lvx 2, 0, 3 -; FORWARD-NEXT: addi 4, 4, 15 -; FORWARD-NEXT: rldicr 3, 4, 0, 59 -; FORWARD-NEXT: addi 4, 3, 16 -; FORWARD-NEXT: std 4, -8(1) -; FORWARD-NEXT: lvx 3, 0, 3 -; FORWARD-NEXT: blr %args = alloca ptr, align 4 %x = va_arg ptr %args, <8 x i32> ret <8 x i32> %x -- GitLab From 919187871d142496d53bca8732677e0811b32409 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Thu, 25 Apr 2024 09:27:45 +0800 Subject: [PATCH 044/733] [PowerPC] Use `SmallSetVector` to enable deterministic build (#89875) This is to address the issue in https://lab.llvm.org/buildbot/#/builders/54. `SmallSetVector` interfaces as set and can be iterated in a deterministic order. --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 6e1002c45d81..51b79dc2b04b 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -27,7 +27,7 @@ #include "PPCTargetStreamer.h" #include "TargetInfo/PowerPCTargetInfo.h" #include "llvm/ADT/MapVector.h" -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" @@ -242,7 +242,7 @@ class PPCAIXAsmPrinter : public PPCAsmPrinter { private: /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern /// linkage for them in AIX. - SmallPtrSet ExtSymSDNodeSymbols; + SmallSetVector ExtSymSDNodeSymbols; /// A format indicator and unique trailing identifier to form part of the /// sinit/sterm function names. -- GitLab From 1b54805dfcebe02f28e23f655c8fbf4dc610aa70 Mon Sep 17 00:00:00 2001 From: Chelsea Cassanova Date: Wed, 24 Apr 2024 18:31:31 -0700 Subject: [PATCH 045/733] [lldb][docs] Update instructions for debugging API tests (#89979) --- lldb/docs/resources/test.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lldb/docs/resources/test.rst b/lldb/docs/resources/test.rst index 094fde8b1b5a..382e42bf22b1 100644 --- a/lldb/docs/resources/test.rst +++ b/lldb/docs/resources/test.rst @@ -618,9 +618,9 @@ On non-Windows platforms, you can use the ``-d`` option to ``dotest.py`` which will cause the script to print out the pid of the test and wait for a while until a debugger is attached. Then run ``lldb -p `` to attach. -To instead debug a test's python source, edit the test and insert -``import pdb; pdb.set_trace()`` at the point you want to start debugging. In -addition to pdb's debugging facilities, lldb commands can be executed with the +To instead debug a test's python source, edit the test and insert ``import pdb; pdb.set_trace()`` or ``breakpoint()`` (Python 3 only) at the point you want to start debugging. The ``breakpoint()`` command can be used for any LLDB Python script, not just for API tests. + +In addition to pdb's debugging facilities, lldb commands can be executed with the help of a pdb alias. For example ``lldb bt`` and ``lldb v some_var``. Add this line to your ``~/.pdbrc``: -- GitLab From d6cc8d45b3da91b8d48c59fa86b6f1dba9c3e87b Mon Sep 17 00:00:00 2001 From: Mircea Trofin Date: Wed, 24 Apr 2024 18:37:20 -0700 Subject: [PATCH 046/733] [buildbot] VE builders: disable ctx_profile (#89969) --- clang/cmake/caches/VectorEngine.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/cmake/caches/VectorEngine.cmake b/clang/cmake/caches/VectorEngine.cmake index e3976f3206db..2f968a21cc40 100644 --- a/clang/cmake/caches/VectorEngine.cmake +++ b/clang/cmake/caches/VectorEngine.cmake @@ -40,6 +40,7 @@ set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_CRT OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "") +set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_CTX_PROFILE OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_PROFILE OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_MEMPROF OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_ORC OFF CACHE BOOL "") @@ -52,6 +53,7 @@ set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "" set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_PROFILE ON CACHE BOOL "") +set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_CTX_PROFILE OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_MEMPROF OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_ORC OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_GWP_ASAN OFF CACHE BOOL "") -- GitLab From 10661ba2403f73cd2c4b76ebd177fdcf9261cbf2 Mon Sep 17 00:00:00 2001 From: Nathan Lanza Date: Wed, 24 Apr 2024 22:26:40 -0400 Subject: [PATCH 047/733] [CIR][NFC] Add scaffolding for the CIR dialect and CIROps.td This adds no real content, it just incrementally adds some scaffolding necessary to enable a future patch to just add our first few ops. Test Plan: ``` $ cmake -Sllvm -Bbuild -DCLANG_ENABLE_CIR=1 \ -DLLVM_ENABLE_PROJECTS='clang;mlir' \ -DCMAKE_BUILD_TYPE=Release -GNinja $ ninja -C build check-clang $ ninja -C build MLIRCIROpsIncGen $ ninja -C build MLIRCIR ``` Reviewers: AaronBallman, erichkeane, bcardosolopes Reviewed By: erichkeane, AaronBallman, bcardosolopes Pull Request: https://github.com/llvm/llvm-project/pull/86080 --- clang/CMakeLists.txt | 4 ++ clang/include/clang/CIR/CMakeLists.txt | 6 +++ .../include/clang/CIR/Dialect/CMakeLists.txt | 1 + .../include/clang/CIR/Dialect/IR/CIRDialect.h | 16 +++++++ .../clang/CIR/Dialect/IR/CIRDialect.td | 44 +++++++++++++++++++ clang/include/clang/CIR/Dialect/IR/CIROps.td | 19 ++++++++ .../clang/CIR/Dialect/IR/CMakeLists.txt | 16 +++++++ clang/lib/CIR/CMakeLists.txt | 4 ++ clang/lib/CIR/Dialect/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 13 ++++++ clang/lib/CIR/Dialect/IR/CMakeLists.txt | 3 ++ 11 files changed, 127 insertions(+) create mode 100644 clang/include/clang/CIR/Dialect/CMakeLists.txt create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRDialect.h create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRDialect.td create mode 100644 clang/include/clang/CIR/Dialect/IR/CIROps.td create mode 100644 clang/include/clang/CIR/Dialect/IR/CMakeLists.txt create mode 100644 clang/lib/CIR/Dialect/CMakeLists.txt create mode 100644 clang/lib/CIR/Dialect/IR/CIRDialect.cpp create mode 100644 clang/lib/CIR/Dialect/IR/CMakeLists.txt diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index f092766fa19f..cf97e3c6e851 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -166,6 +166,10 @@ if(CLANG_ENABLE_LIBXML2) endif() if(CLANG_ENABLE_CIR) + if (CLANG_BUILT_STANDALONE) + message(FATAL_ERROR + "ClangIR is not yet supported in the standalone build.") + endif() if (NOT "${LLVM_ENABLE_PROJECTS}" MATCHES "MLIR|mlir") message(FATAL_ERROR "Cannot build ClangIR without MLIR in LLVM_ENABLE_PROJECTS") diff --git a/clang/include/clang/CIR/CMakeLists.txt b/clang/include/clang/CIR/CMakeLists.txt index e69de29bb2d1..f8d6f407a03d 100644 --- a/clang/include/clang/CIR/CMakeLists.txt +++ b/clang/include/clang/CIR/CMakeLists.txt @@ -0,0 +1,6 @@ +set(MLIR_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/../mlir/include ) # --includedir +set(MLIR_TABLEGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/tools/mlir/include) +include_directories(${MLIR_INCLUDE_DIR}) +include_directories(${MLIR_TABLEGEN_OUTPUT_DIR}) + +add_subdirectory(Dialect) diff --git a/clang/include/clang/CIR/Dialect/CMakeLists.txt b/clang/include/clang/CIR/Dialect/CMakeLists.txt new file mode 100644 index 000000000000..f33061b2d87c --- /dev/null +++ b/clang/include/clang/CIR/Dialect/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(IR) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h new file mode 100644 index 000000000000..d53e5d1663d6 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h @@ -0,0 +1,16 @@ +//===- CIRDialect.h - CIR dialect -------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the CIR dialect. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H +#define LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td new file mode 100644 index 000000000000..69d6e9774942 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td @@ -0,0 +1,44 @@ +//===- CIRDialect.td - CIR dialect -------------------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the CIR dialect. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT +#define LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT + +include "mlir/IR/OpBase.td" + +def CIR_Dialect : Dialect { + let name = "cir"; + + // A short one-line summary of our dialect. + let summary = "A high-level dialect for analyzing and optimizing Clang " + "supported languages"; + + let cppNamespace = "::mlir::cir"; + + let useDefaultAttributePrinterParser = 0; + let useDefaultTypePrinterParser = 0; + + let extraClassDeclaration = [{ + void registerAttributes(); + void registerTypes(); + + Type parseType(DialectAsmParser &parser) const override; + void printType(Type type, DialectAsmPrinter &printer) const override; + + Attribute parseAttribute(DialectAsmParser &parser, + Type type) const override; + + void printAttribute(Attribute attr, DialectAsmPrinter &os) const override; + }]; +} + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td new file mode 100644 index 000000000000..7311c8db783e --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -0,0 +1,19 @@ +//===-- CIROps.td - CIR dialect definition -----------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Definition of the CIR dialect +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIROPS +#define LLVM_CLANG_CIR_DIALECT_IR_CIROPS + +include "clang/CIR/Dialect/IR/CIRDialect.td" + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIROPS diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt new file mode 100644 index 000000000000..28ae30dab8df --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt @@ -0,0 +1,16 @@ +# This replicates part of the add_mlir_dialect cmake function from MLIR that +# cannot be used here. This happens because it expects to be run inside MLIR +# directory which is not the case for CIR (and also FIR, both have similar +# workarounds). + +# Equivalent to add_mlir_dialect(CIROps cir) +set(LLVM_TARGET_DEFINITIONS CIROps.td) +mlir_tablegen(CIROps.h.inc -gen-op-decls) +mlir_tablegen(CIROps.cpp.inc -gen-op-defs) +mlir_tablegen(CIROpsTypes.h.inc -gen-typedef-decls) +mlir_tablegen(CIROpsTypes.cpp.inc -gen-typedef-defs) +mlir_tablegen(CIROpsDialect.h.inc -gen-dialect-decls) +mlir_tablegen(CIROpsDialect.cpp.inc -gen-dialect-defs) +add_public_tablegen_target(MLIRCIROpsIncGen) +add_dependencies(mlir-headers MLIRCIROpsIncGen) + diff --git a/clang/lib/CIR/CMakeLists.txt b/clang/lib/CIR/CMakeLists.txt index e69de29bb2d1..d2ff200e0da5 100644 --- a/clang/lib/CIR/CMakeLists.txt +++ b/clang/lib/CIR/CMakeLists.txt @@ -0,0 +1,4 @@ +include_directories(${LLVM_MAIN_SRC_DIR}/../mlir/include) +include_directories(${CMAKE_BINARY_DIR}/tools/mlir/include) + +add_subdirectory(Dialect) diff --git a/clang/lib/CIR/Dialect/CMakeLists.txt b/clang/lib/CIR/Dialect/CMakeLists.txt new file mode 100644 index 000000000000..f33061b2d87c --- /dev/null +++ b/clang/lib/CIR/Dialect/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(IR) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp new file mode 100644 index 000000000000..c2829c3ff2af --- /dev/null +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -0,0 +1,13 @@ +//===- CIRDialect.cpp - MLIR CIR ops implementation -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the CIR dialect and its operations. +// +//===----------------------------------------------------------------------===// + +#include diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt b/clang/lib/CIR/Dialect/IR/CMakeLists.txt new file mode 100644 index 000000000000..0d7476b55570 --- /dev/null +++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt @@ -0,0 +1,3 @@ +add_clang_library(MLIRCIR + CIRDialect.cpp + ) -- GitLab From 090c92e01586fc515d584b1367b1b5928277c7f2 Mon Sep 17 00:00:00 2001 From: Amir Ayupov Date: Thu, 25 Apr 2024 04:53:15 +0200 Subject: [PATCH 048/733] [BOLT] Emit synthetic FILE symbol for local cold fragments of global symbols (#89794) --- bolt/include/bolt/Rewrite/RewriteInstance.h | 3 +++ bolt/lib/Rewrite/RewriteInstance.cpp | 16 ++++++++++++++++ bolt/test/X86/cdsplit-symbol-names.s | 1 + 3 files changed, 20 insertions(+) diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h index af832b4c7c84..2561468a0f99 100644 --- a/bolt/include/bolt/Rewrite/RewriteInstance.h +++ b/bolt/include/bolt/Rewrite/RewriteInstance.h @@ -426,6 +426,9 @@ private: static StringRef getEHFrameSectionName() { return ".eh_frame"; } static StringRef getRelaDynSectionName() { return ".rela.dyn"; } + /// FILE symbol name used for local fragments of global functions. + static StringRef getBOLTFileSymbolName() { return "bolt-pseudo.o"; } + /// An instance of the input binary we are processing, externally owned. llvm::object::ELFObjectFileBase *InputFile; diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 21fa15b6a11f..a6b2f3cc0850 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -4493,6 +4493,8 @@ void RewriteInstance::updateELFSymbolTable( // Symbols for the new symbol table. std::vector Symbols; + bool EmittedColdFileSymbol = false; + auto getNewSectionIndex = [&](uint32_t OldIndex) { // For dynamic symbol table, the section index could be wrong on the input, // and its value is ignored by the runtime if it's different from @@ -4551,6 +4553,20 @@ void RewriteInstance::updateELFSymbolTable( Symbols.emplace_back(ICFSymbol); } if (Function.isSplit()) { + // Prepend synthetic FILE symbol to prevent local cold fragments from + // colliding with existing symbols with the same name. + if (!EmittedColdFileSymbol && + FunctionSymbol.getBinding() == ELF::STB_GLOBAL) { + ELFSymTy FileSymbol; + FileSymbol.st_shndx = ELF::SHN_ABS; + FileSymbol.st_name = AddToStrTab(getBOLTFileSymbolName()); + FileSymbol.st_value = 0; + FileSymbol.st_size = 0; + FileSymbol.st_other = 0; + FileSymbol.setBindingAndType(ELF::STB_LOCAL, ELF::STT_FILE); + Symbols.emplace_back(FileSymbol); + EmittedColdFileSymbol = true; + } for (const FunctionFragment &FF : Function.getLayout().getSplitFragments()) { if (FF.getAddress()) { diff --git a/bolt/test/X86/cdsplit-symbol-names.s b/bolt/test/X86/cdsplit-symbol-names.s index e2259276e255..e53863e22246 100644 --- a/bolt/test/X86/cdsplit-symbol-names.s +++ b/bolt/test/X86/cdsplit-symbol-names.s @@ -10,6 +10,7 @@ # RUN: --call-scale=2 --data=%t.fdata --reorder-blocks=ext-tsp # RUN: llvm-objdump --syms %t.bolt | FileCheck %s --check-prefix=CHECK-SYMS-WARM +# CHECK-SYMS-WARM: 0000000000000000 l df *ABS* 0000000000000000 bolt-pseudo.o # CHECK-SYMS-WARM: .text.warm # CHECK-SYMS-WARM-SAME: chain.warm # CHECK-SYMS-WARM: .text.cold -- GitLab From 865b73ae457bcc5fb121f8180d4cfeba57e6f2ac Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 25 Apr 2024 13:45:23 +0900 Subject: [PATCH 049/733] [InstCombine] Add multi-use tests for shift-of-shift transform (NFC) Also drop irrelevant function attributes from tests. --- llvm/test/Transforms/InstCombine/shift.ll | 64 ++++++++++++++++------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll index 5692202fcb4c..8da52e074637 100644 --- a/llvm/test/Transforms/InstCombine/shift.ll +++ b/llvm/test/Transforms/InstCombine/shift.ll @@ -366,7 +366,7 @@ define i32 @test26(i32 %A) { ret i32 %D } -define i1 @test27(i32 %x) nounwind { +define i1 @test27(i32 %x) { ; CHECK-LABEL: @test27( ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 8 ; CHECK-NEXT: [[Z:%.*]] = icmp ne i32 [[TMP1]], 0 @@ -605,7 +605,7 @@ define <2 x i32> @shl_nuw_nsw_splat_vec(<2 x i8> %x) { ret <2 x i32> %t3 } -define i32 @test38(i32 %x) nounwind readnone { +define i32 @test38(i32 %x) { ; CHECK-LABEL: @test38( ; CHECK-NEXT: [[REM1:%.*]] = and i32 [[X:%.*]], 31 ; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[REM1]] @@ -616,7 +616,7 @@ define i32 @test38(i32 %x) nounwind readnone { ret i32 %shl } -define <2 x i32> @test38_uniform(<2 x i32> %x) nounwind readnone { +define <2 x i32> @test38_uniform(<2 x i32> %x) { ; CHECK-LABEL: @test38_uniform( ; CHECK-NEXT: [[REM1:%.*]] = and <2 x i32> [[X:%.*]], ; CHECK-NEXT: [[SHL:%.*]] = shl nuw <2 x i32> , [[REM1]] @@ -627,7 +627,7 @@ define <2 x i32> @test38_uniform(<2 x i32> %x) nounwind readnone { ret <2 x i32> %shl } -define <3 x i32> @test38_nonuniform(<3 x i32> %x) nounwind readnone { +define <3 x i32> @test38_nonuniform(<3 x i32> %x) { ; CHECK-LABEL: @test38_nonuniform( ; CHECK-NEXT: [[REM1:%.*]] = and <3 x i32> [[X:%.*]], ; CHECK-NEXT: [[SHL:%.*]] = shl nuw <3 x i32> , [[REM1]] @@ -638,7 +638,7 @@ define <3 x i32> @test38_nonuniform(<3 x i32> %x) nounwind readnone { ret <3 x i32> %shl } -define <2 x i32> @test38_poison(<2 x i32> %x) nounwind readnone { +define <2 x i32> @test38_poison(<2 x i32> %x) { ; CHECK-LABEL: @test38_poison( ; CHECK-NEXT: ret <2 x i32> poison ; @@ -658,8 +658,8 @@ define i8 @test39(i32 %a0) { ; CHECK-NEXT: [[I51:%.*]] = xor i8 [[I50]], [[I5]] ; CHECK-NEXT: [[TMP0:%.*]] = lshr exact i8 [[I5]], 3 ; CHECK-NEXT: [[I54:%.*]] = and i8 [[TMP0]], 16 -; CHECK-NEXT: [[I551:%.*]] = or disjoint i8 [[I54]], [[I51]] -; CHECK-NEXT: ret i8 [[I551]] +; CHECK-NEXT: [[I55:%.*]] = or disjoint i8 [[I54]], [[I51]] +; CHECK-NEXT: ret i8 [[I55]] ; entry: %i4 = trunc i32 %a0 to i8 @@ -675,7 +675,7 @@ entry: ret i8 %i55 } -define i32 @test42(i32 %a, i32 %b) nounwind { +define i32 @test42(i32 %a, i32 %b) { ; CHECK-LABEL: @test42( ; CHECK-NEXT: [[DIV:%.*]] = lshr exact i32 4096, [[B:%.*]] ; CHECK-NEXT: [[DIV2:%.*]] = udiv i32 [[A:%.*]], [[DIV]] @@ -697,7 +697,7 @@ define <2 x i32> @test42vec(<2 x i32> %a, <2 x i32> %b) { ret <2 x i32> %div2 } -define i32 @test43(i32 %a, i32 %b) nounwind { +define i32 @test43(i32 %a, i32 %b) { ; CHECK-LABEL: @test43( ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[B:%.*]], 12 ; CHECK-NEXT: [[DIV21:%.*]] = lshr i32 [[A:%.*]], [[TMP1]] @@ -708,7 +708,7 @@ define i32 @test43(i32 %a, i32 %b) nounwind { ret i32 %div2 } -define i32 @test44(i32 %a) nounwind { +define i32 @test44(i32 %a) { ; CHECK-LABEL: @test44( ; CHECK-NEXT: [[Y:%.*]] = shl i32 [[A:%.*]], 5 ; CHECK-NEXT: ret i32 [[Y]] @@ -718,7 +718,20 @@ define i32 @test44(i32 %a) nounwind { ret i32 %z } -define i32 @test45(i32 %a) nounwind { +define i32 @test44_multiuse(i32 %a) { +; CHECK-LABEL: @test44_multiuse( +; CHECK-NEXT: [[Y:%.*]] = shl nuw i32 [[A:%.*]], 1 +; CHECK-NEXT: call void @use_i32(i32 [[Y]]) +; CHECK-NEXT: [[Z:%.*]] = shl i32 [[A]], 5 +; CHECK-NEXT: ret i32 [[Z]] +; + %y = shl nuw i32 %a, 1 + call void @use_i32(i32 %y) + %z = shl i32 %y, 4 + ret i32 %z +} + +define i32 @test45(i32 %a) { ; CHECK-LABEL: @test45( ; CHECK-NEXT: [[Y:%.*]] = lshr i32 [[A:%.*]], 5 ; CHECK-NEXT: ret i32 [[Y]] @@ -728,6 +741,19 @@ define i32 @test45(i32 %a) nounwind { ret i32 %z } +define i32 @test45_multiuse(i32 %a) { +; CHECK-LABEL: @test45_multiuse( +; CHECK-NEXT: [[Y:%.*]] = lshr exact i32 [[A:%.*]], 1 +; CHECK-NEXT: call void @use_i32(i32 [[Y]]) +; CHECK-NEXT: [[Z:%.*]] = lshr i32 [[A]], 5 +; CHECK-NEXT: ret i32 [[Z]] +; + %y = lshr exact i32 %a, 1 + call void @use_i32(i32 %y) + %z = lshr i32 %y, 4 + ret i32 %z +} + ; (X >>?exact C1) << C2 --> X >>?exact (C1-C2) define i32 @test46(i32 %a) { @@ -1751,14 +1777,14 @@ define void @ashr_out_of_range_1(ptr %A) { ; CHECK-NEXT: [[L:%.*]] = load i177, ptr [[A:%.*]], align 4 ; CHECK-NEXT: [[L_FROZEN:%.*]] = freeze i177 [[L]] ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L_FROZEN]], -1 -; CHECK-NEXT: [[TMP6:%.*]] = trunc i177 [[L_FROZEN]] to i64 -; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP6]] -; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP2]] -; CHECK-NEXT: [[G11:%.*]] = getelementptr i8, ptr [[TMP3]], i64 -24 -; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[TMP1]] to i64 -; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP4]] -; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i177 [[L_FROZEN]], -1 -; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP5]], i177 0, i177 [[L_FROZEN]] +; CHECK-NEXT: [[TMP2:%.*]] = trunc i177 [[L_FROZEN]] to i64 +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 0, i64 [[TMP2]] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP3]] +; CHECK-NEXT: [[G11:%.*]] = getelementptr i8, ptr [[TMP4]], i64 -24 +; CHECK-NEXT: [[TMP5:%.*]] = sext i1 [[TMP1]] to i64 +; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP5]] +; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i177 [[L_FROZEN]], -1 +; CHECK-NEXT: [[B28:%.*]] = select i1 [[TMP6]], i177 0, i177 [[L_FROZEN]] ; CHECK-NEXT: store i177 [[B28]], ptr [[G62]], align 4 ; CHECK-NEXT: ret void ; -- GitLab From 4b10ade1a6afa1fcff5752aaebd86a1611d499d7 Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Wed, 24 Apr 2024 21:46:45 -0700 Subject: [PATCH 050/733] [clang-format] Annotate enum braces as BK_Block (#89871) Fixes #89759. --- clang/lib/Format/UnwrappedLineParser.cpp | 24 +++++++++---------- clang/unittests/Format/TokenAnnotatorTest.cpp | 17 +++++++++++++ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 6e4e6901e473..3a263955a6a8 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -534,11 +534,11 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { case tok::r_brace: if (LBraceStack.empty()) break; - if (LBraceStack.back().Tok->is(BK_Unknown)) { + if (auto *LBrace = LBraceStack.back().Tok; LBrace->is(BK_Unknown)) { bool ProbablyBracedList = false; if (Style.Language == FormatStyle::LK_Proto) { ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square); - } else { + } else if (LBrace->isNot(TT_EnumLBrace)) { // Using OriginalColumn to distinguish between ObjC methods and // binary operators is a bit hacky. bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) && @@ -552,7 +552,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { // If we already marked the opening brace as braced list, the closing // must also be part of it. - ProbablyBracedList = LBraceStack.back().Tok->is(TT_BracedListLBrace); + ProbablyBracedList = LBrace->is(TT_BracedListLBrace); ProbablyBracedList = ProbablyBracedList || (Style.isJavaScript() && @@ -608,13 +608,9 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { ProbablyBracedList = true; } } - if (ProbablyBracedList) { - Tok->setBlockKind(BK_BracedInit); - LBraceStack.back().Tok->setBlockKind(BK_BracedInit); - } else { - Tok->setBlockKind(BK_Block); - LBraceStack.back().Tok->setBlockKind(BK_Block); - } + const auto BlockKind = ProbablyBracedList ? BK_BracedInit : BK_Block; + Tok->setBlockKind(BlockKind); + LBrace->setBlockKind(BlockKind); } LBraceStack.pop_back(); break; @@ -2418,6 +2414,7 @@ bool UnwrappedLineParser::tryToParseChildBlock() { } bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) { + assert(!IsAngleBracket || !IsEnum); bool HasError = false; // FIXME: Once we have an expression parser in the UnwrappedLineParser, @@ -2440,8 +2437,11 @@ bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) { } } if (FormatTok->is(IsAngleBracket ? tok::greater : tok::r_brace)) { - if (IsEnum && !Style.AllowShortEnumsOnASingleLine) - addUnwrappedLine(); + if (IsEnum) { + FormatTok->setBlockKind(BK_Block); + if (!Style.AllowShortEnumsOnASingleLine) + addUnwrappedLine(); + } nextToken(); return !HasError; } diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 6b8ab441cb46..dff5251d2e94 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -2915,6 +2915,23 @@ TEST_F(TokenAnnotatorTest, BraceKind) { ASSERT_EQ(Tokens.size(), 10u) << Tokens; EXPECT_BRACE_KIND(Tokens[6], BK_BracedInit); EXPECT_BRACE_KIND(Tokens[7], BK_BracedInit); + + Tokens = annotate("#ifdef DEBUG_ENABLED\n" + "#else\n" + "#endif\n" + "class RenderingServer : Object {\n" + "#ifndef DISABLE_DEPRECATED\n" + " enum Features {\n" + " FEATURE_SHADERS,\n" + " FEATURE_MULTITHREADED,\n" + " };\n" + "#endif\n" + "};"); + ASSERT_EQ(Tokens.size(), 29u) << Tokens; + EXPECT_BRACE_KIND(Tokens[11], BK_Block); + EXPECT_BRACE_KIND(Tokens[17], BK_Block); + EXPECT_BRACE_KIND(Tokens[22], BK_Block); + EXPECT_BRACE_KIND(Tokens[26], BK_Block); } TEST_F(TokenAnnotatorTest, UnderstandsElaboratedTypeSpecifier) { -- GitLab From 873889b7fa23434876533c603e687fc70396b0ab Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 25 Apr 2024 14:13:52 +0900 Subject: [PATCH 051/733] [InstCombine] Extract logic for "emit offset and rewrite gep" (NFC) --- .../InstCombine/InstCombineCasts.cpp | 6 ++--- .../InstCombine/InstCombineCompares.cpp | 24 ++----------------- .../InstCombine/InstCombineInternal.h | 2 +- .../InstCombine/InstructionCombining.cpp | 22 +++++++++++++++-- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 6ce39be59bda..567b27b46304 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -2050,9 +2050,9 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) { // the GEP otherwise. if (GEP->hasOneUse() && isa(GEP->getPointerOperand())) { - return replaceInstUsesWith(CI, - Builder.CreateIntCast(EmitGEPOffset(GEP), Ty, - /*isSigned=*/false)); + return replaceInstUsesWith( + CI, Builder.CreateIntCast(EmitGEPOffset(cast(GEP)), Ty, + /*isSigned=*/false)); } } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index c2062adcd5b7..1064340cb536 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -816,29 +816,9 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, } if (GEPsInBounds || CmpInst::isEquality(Cond)) { - auto EmitGEPOffsetAndRewrite = [&](GEPOperator *GEP) { - IRBuilderBase::InsertPointGuard Guard(Builder); - auto *Inst = dyn_cast(GEP); - if (Inst) - Builder.SetInsertPoint(Inst); - - Value *Offset = EmitGEPOffset(GEP); - // If a non-trivial GEP has other uses, rewrite it to avoid duplicating - // the offset arithmetic. - if (Inst && !GEP->hasOneUse() && !GEP->hasAllConstantIndices() && - !GEP->getSourceElementType()->isIntegerTy(8)) { - replaceInstUsesWith(*Inst, - Builder.CreateGEP(Builder.getInt8Ty(), - GEP->getPointerOperand(), - Offset, "", GEPsInBounds)); - eraseInstFromFunction(*Inst); - } - return Offset; - }; - // ((gep Ptr, OFFSET1) cmp (gep Ptr, OFFSET2) ---> (OFFSET1 cmp OFFSET2) - Value *L = EmitGEPOffsetAndRewrite(GEPLHS); - Value *R = EmitGEPOffsetAndRewrite(GEPRHS); + Value *L = EmitGEPOffset(GEPLHS, /*RewriteGEP=*/true); + Value *R = EmitGEPOffset(GEPRHS, /*RewriteGEP=*/true); return new ICmpInst(ICmpInst::getSignedPredicate(Cond), L, R); } } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index 4479afbd09af..aafb4cf6ca6a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -376,7 +376,7 @@ private: } } - Value *EmitGEPOffset(User *GEP); + Value *EmitGEPOffset(GEPOperator *GEP, bool RewriteGEP = false); Instruction *scalarizePHI(ExtractElementInst &EI, PHINode *PN); Instruction *foldBitcastExtElt(ExtractElementInst &ExtElt); Instruction *foldCastedBitwiseLogic(BinaryOperator &I); diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index f6684834a772..282badd43693 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -190,8 +190,26 @@ bool InstCombiner::isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const { return TTI.isValidAddrSpaceCast(FromAS, ToAS); } -Value *InstCombinerImpl::EmitGEPOffset(User *GEP) { - return llvm::emitGEPOffset(&Builder, DL, GEP); +Value *InstCombinerImpl::EmitGEPOffset(GEPOperator *GEP, bool RewriteGEP) { + if (!RewriteGEP) + return llvm::emitGEPOffset(&Builder, DL, GEP); + + IRBuilderBase::InsertPointGuard Guard(Builder); + auto *Inst = dyn_cast(GEP); + if (Inst) + Builder.SetInsertPoint(Inst); + + Value *Offset = EmitGEPOffset(GEP); + // If a non-trivial GEP has other uses, rewrite it to avoid duplicating + // the offset arithmetic. + if (Inst && !GEP->hasOneUse() && !GEP->hasAllConstantIndices() && + !GEP->getSourceElementType()->isIntegerTy(8)) { + replaceInstUsesWith( + *Inst, Builder.CreateGEP(Builder.getInt8Ty(), GEP->getPointerOperand(), + Offset, "", GEP->isInBounds())); + eraseInstFromFunction(*Inst); + } + return Offset; } /// Legal integers and common types are considered desirable. This is used to -- GitLab From 7a77b763af3b6ac3218b9cf574d7d65f3196a4ec Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 25 Apr 2024 14:24:08 +0900 Subject: [PATCH 052/733] [InstCombine] Add additional multi-use test for sub of gep (NFC) A case where still performing the fold is clearly profitable. --- llvm/test/Transforms/InstCombine/sub.ll | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/llvm/test/Transforms/InstCombine/sub.ll b/llvm/test/Transforms/InstCombine/sub.ll index a84e389f13c3..56dd9c6a8799 100644 --- a/llvm/test/Transforms/InstCombine/sub.ll +++ b/llvm/test/Transforms/InstCombine/sub.ll @@ -1180,6 +1180,27 @@ define i64 @test61(ptr %foo, i64 %i, i64 %j) { ret i64 %sub } +declare void @use.ptr(ptr) + +define i64 @test_sub_ptradd_multiuse(ptr %p, i64 %idx1, i64 %idx2) { +; CHECK-LABEL: @test_sub_ptradd_multiuse( +; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[IDX1:%.*]] +; CHECK-NEXT: call void @use.ptr(ptr [[P1]]) +; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[IDX2:%.*]] +; CHECK-NEXT: [[P1_INT:%.*]] = ptrtoint ptr [[P1]] to i64 +; CHECK-NEXT: [[P2_INT:%.*]] = ptrtoint ptr [[P2]] to i64 +; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[P1_INT]], [[P2_INT]] +; CHECK-NEXT: ret i64 [[SUB]] +; + %p1 = getelementptr inbounds i8, ptr %p, i64 %idx1 + call void @use.ptr(ptr %p1) + %p2 = getelementptr inbounds i8, ptr %p, i64 %idx2 + %p1.int = ptrtoint ptr %p1 to i64 + %p2.int = ptrtoint ptr %p2 to i64 + %sub = sub i64 %p1.int, %p2.int + ret i64 %sub +} + define i32 @test62(i32 %A) { ; CHECK-LABEL: @test62( ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[A:%.*]], 1 -- GitLab From fd5f06eb6d8d8b05846c8d7bd2431079ef707b37 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Thu, 25 Apr 2024 08:46:04 +0300 Subject: [PATCH 053/733] [clang-repl] Fix the process return code if diagnostics occurred. (#89879) Should fix the failure seen in the pre-merge infrastructure of #89804. --- clang/test/Interpreter/fail.cpp | 21 ++++++++++++++------- clang/tools/clang-repl/ClangRepl.cpp | 17 +++++++---------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/clang/test/Interpreter/fail.cpp b/clang/test/Interpreter/fail.cpp index 4e301f37548f..633d92794325 100644 --- a/clang/test/Interpreter/fail.cpp +++ b/clang/test/Interpreter/fail.cpp @@ -1,12 +1,19 @@ -// FIXME: There're some inconsistencies between interactive and non-interactive -// modes. For example, when clang-repl runs in the interactive mode, issues an -// error, and then successfully recovers if we decide it's a success then for -// the non-interactive mode the exit code should be a failure. -// RUN: clang-repl "int x = 10;" "int y=7; err;" "int y = 10;" // REQUIRES: host-supports-jit // UNSUPPORTED: system-aix -// RUN: cat %s | not clang-repl | FileCheck %s -BOOM! +// clang-repl can be called from the prompt in non-interactive mode as a +// calculator in shell scripts, for example. In that case if there is an error +// we should set the exit code as failure. +// RUN: not clang-repl "int x = 10;" "int y=7; err;" "int y = 10;" + +// In interactive (REPL) mode, we can have errors but we should exit with +// success because errors in the input code are part of the interactive use. +// RUN: cat %s | clang-repl | FileCheck %s + +// However, interactive mode should fail when we specified -verify and there +// was a diagnostic mismatches. This will make the testsuite fail as intended. +// RUN: cat %s | not clang-repl -Xcc -Xclang -Xcc -verify | FileCheck %s + +BOOM! // expected-error {{intended to fail the -verify test}} extern "C" int printf(const char *, ...); int i = 42; auto r1 = printf("i = %d\n", i); diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index aecf61b97fc7..9cfc70462893 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -215,13 +215,15 @@ int main(int argc, const char **argv) { } else Interp = ExitOnErr(clang::Interpreter::create(std::move(CI))); + bool HasError = false; + for (const std::string &input : OptInputs) { - if (auto Err = Interp->ParseAndExecute(input)) + if (auto Err = Interp->ParseAndExecute(input)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); + HasError = true; + } } - bool HasError = false; - if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); std::string Input; @@ -241,18 +243,13 @@ int main(int argc, const char **argv) { break; } if (Input == R"(%undo)") { - if (auto Err = Interp->Undo()) { + if (auto Err = Interp->Undo()) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; - } } else if (Input.rfind("%lib ", 0) == 0) { - if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) { + if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; - } } else if (auto Err = Interp->ParseAndExecute(Input)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; } Input = ""; -- GitLab From c2a98fdeb3aede1a8db492a6ea30f4fa85b60edc Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Thu, 25 Apr 2024 13:53:22 +0800 Subject: [PATCH 054/733] [NFC] Move DeclID from serialization/ASTBitCodes.h to AST/DeclID.h (#89873) Previously, the DeclID is defined in serialization/ASTBitCodes.h under clang::serialization namespace. However, actually the DeclID is not purely used in serialization part. The DeclID is already widely used in AST and all around the clang project via classes like `LazyPtrDecl` or calling `ExternalASTSource::getExernalDecl()`. All such uses are via the raw underlying type of `DeclID` as `uint32_t`. This is not pretty good. This patch moves the DeclID class family to a new header `AST/DeclID.h` so that the whole project can use the wrapped class `DeclID`, `GlobalDeclID` and `LocalDeclID` instead of the raw underlying type. This can improve the readability and the type safety. --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/AST/DeclBase.h | 4 +- clang/include/clang/AST/DeclID.h | 177 ++++++++++++++++++ clang/include/clang/AST/DeclTemplate.h | 2 +- clang/include/clang/AST/ExternalASTSource.h | 4 +- clang/include/clang/Frontend/ASTUnit.h | 2 +- .../clang/Frontend/MultiplexConsumer.h | 2 +- .../clang/Sema/MultiplexExternalSemaSource.h | 2 +- .../include/clang/Serialization/ASTBitCodes.h | 161 +--------------- .../ASTDeserializationListener.h | 2 +- clang/include/clang/Serialization/ASTReader.h | 126 ++++++------- .../clang/Serialization/ASTRecordReader.h | 6 +- clang/include/clang/Serialization/ASTWriter.h | 22 +-- .../include/clang/Serialization/ModuleFile.h | 8 +- clang/lib/AST/ASTContext.cpp | 3 +- clang/lib/AST/Decl.cpp | 46 ++--- clang/lib/AST/DeclBase.cpp | 4 +- clang/lib/AST/DeclCXX.cpp | 63 +++---- clang/lib/AST/DeclFriend.cpp | 2 +- clang/lib/AST/DeclObjC.cpp | 24 +-- clang/lib/AST/DeclOpenMP.cpp | 18 +- clang/lib/AST/DeclTemplate.cpp | 41 ++-- clang/lib/AST/ExternalASTSource.cpp | 2 +- clang/lib/Frontend/ASTUnit.cpp | 4 +- clang/lib/Frontend/FrontendAction.cpp | 6 +- clang/lib/Frontend/MultiplexConsumer.cpp | 3 +- .../lib/Sema/MultiplexExternalSemaSource.cpp | 2 +- clang/lib/Serialization/ASTReader.cpp | 16 +- clang/lib/Serialization/ASTReaderDecl.cpp | 18 +- clang/lib/Serialization/ASTWriter.cpp | 4 +- clang/lib/Serialization/ASTWriterDecl.cpp | 4 +- 31 files changed, 384 insertions(+), 398 deletions(-) create mode 100644 clang/include/clang/AST/DeclID.h diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index d5ed20ff5015..ecec9bfcf300 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -455,7 +455,7 @@ class ASTContext : public RefCountedBase { /// initialization of another module). struct PerModuleInitializers { llvm::SmallVector Initializers; - llvm::SmallVector LazyInitializers; + llvm::SmallVector LazyInitializers; void resolve(ASTContext &Ctx); }; @@ -1059,7 +1059,7 @@ public: /// or an ImportDecl nominating another module that has initializers. void addModuleInitializer(Module *M, Decl *Init); - void addLazyModuleInitializers(Module *M, ArrayRef IDs); + void addLazyModuleInitializers(Module *M, ArrayRef IDs); /// Get the initializations to perform when importing a module, if any. ArrayRef getModuleInitializers(Module *M); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index d8cafc3d8152..474e51c1df6d 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -15,6 +15,7 @@ #include "clang/AST/ASTDumperUtils.h" #include "clang/AST/AttrIterator.h" +#include "clang/AST/DeclID.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/SelectorLocationsKind.h" #include "clang/Basic/IdentifierTable.h" @@ -239,9 +240,6 @@ public: ModulePrivate }; - /// An ID number that refers to a declaration in an AST file. - using DeclID = uint32_t; - protected: /// The next declaration within the same lexical /// DeclContext. These pointers form the linked list that is diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h new file mode 100644 index 000000000000..e2c6dd65e86b --- /dev/null +++ b/clang/include/clang/AST/DeclID.h @@ -0,0 +1,177 @@ +//===--- DeclID.h - ID number for deserialized declarations ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines DeclID class family to describe the deserialized +// declarations. The DeclID is widely used in AST via LazyDeclPtr, or calls to +// `ExternalASTSource::getExternalDecl`. It will be helpful for type safety to +// require the use of `DeclID` to explicit. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLID_H +#define LLVM_CLANG_AST_DECLID_H + +#include "llvm/ADT/iterator.h" + +namespace clang { + +/// Predefined declaration IDs. +/// +/// These declaration IDs correspond to predefined declarations in the AST +/// context, such as the NULL declaration ID. Such declarations are never +/// actually serialized, since they will be built by the AST context when +/// it is created. +enum PredefinedDeclIDs { + /// The NULL declaration. + PREDEF_DECL_NULL_ID = 0, + + /// The translation unit. + PREDEF_DECL_TRANSLATION_UNIT_ID = 1, + + /// The Objective-C 'id' type. + PREDEF_DECL_OBJC_ID_ID = 2, + + /// The Objective-C 'SEL' type. + PREDEF_DECL_OBJC_SEL_ID = 3, + + /// The Objective-C 'Class' type. + PREDEF_DECL_OBJC_CLASS_ID = 4, + + /// The Objective-C 'Protocol' type. + PREDEF_DECL_OBJC_PROTOCOL_ID = 5, + + /// The signed 128-bit integer type. + PREDEF_DECL_INT_128_ID = 6, + + /// The unsigned 128-bit integer type. + PREDEF_DECL_UNSIGNED_INT_128_ID = 7, + + /// The internal 'instancetype' typedef. + PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8, + + /// The internal '__builtin_va_list' typedef. + PREDEF_DECL_BUILTIN_VA_LIST_ID = 9, + + /// The internal '__va_list_tag' struct, if any. + PREDEF_DECL_VA_LIST_TAG = 10, + + /// The internal '__builtin_ms_va_list' typedef. + PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11, + + /// The predeclared '_GUID' struct. + PREDEF_DECL_BUILTIN_MS_GUID_ID = 12, + + /// The extern "C" context. + PREDEF_DECL_EXTERN_C_CONTEXT_ID = 13, + + /// The internal '__make_integer_seq' template. + PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 14, + + /// The internal '__NSConstantString' typedef. + PREDEF_DECL_CF_CONSTANT_STRING_ID = 15, + + /// The internal '__NSConstantString' tag type. + PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 16, + + /// The internal '__type_pack_element' template. + PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17, +}; + +/// The number of declaration IDs that are predefined. +/// +/// For more information about predefined declarations, see the +/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. +const unsigned int NUM_PREDEF_DECL_IDS = 18; + +/// An ID number that refers to a declaration in an AST file. +/// +/// The ID numbers of declarations are consecutive (in order of +/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. +/// At the start of a chain of precompiled headers, declaration ID 1 is +/// used for the translation unit declaration. +using DeclID = uint32_t; + +class LocalDeclID { +public: + explicit LocalDeclID(DeclID ID) : ID(ID) {} + + DeclID get() const { return ID; } + +private: + DeclID ID; +}; + +/// Wrapper class for DeclID. This is helpful to not mix the use of LocalDeclID +/// and GlobalDeclID to improve the type safety. +class GlobalDeclID { +public: + GlobalDeclID() : ID(PREDEF_DECL_NULL_ID) {} + explicit GlobalDeclID(DeclID ID) : ID(ID) {} + + DeclID get() const { return ID; } + + explicit operator DeclID() const { return ID; } + + friend bool operator==(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + return LHS.ID == RHS.ID; + } + friend bool operator!=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + return LHS.ID != RHS.ID; + } + // We may sort the global decl ID. + friend bool operator<(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + return LHS.ID < RHS.ID; + } + friend bool operator>(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + return LHS.ID > RHS.ID; + } + friend bool operator<=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + return LHS.ID <= RHS.ID; + } + friend bool operator>=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + return LHS.ID >= RHS.ID; + } + +private: + DeclID ID; +}; + +/// A helper iterator adaptor to convert the iterators to `SmallVector` +/// to the iterators to `SmallVector`. +class GlobalDeclIDIterator + : public llvm::iterator_adaptor_base { +public: + GlobalDeclIDIterator() : iterator_adaptor_base(nullptr) {} + + GlobalDeclIDIterator(const DeclID *ID) : iterator_adaptor_base(ID) {} + + value_type operator*() const { return GlobalDeclID(*I); } + + bool operator==(const GlobalDeclIDIterator &RHS) const { return I == RHS.I; } +}; + +/// A helper iterator adaptor to convert the iterators to +/// `SmallVector` to the iterators to `SmallVector`. +class DeclIDIterator + : public llvm::iterator_adaptor_base { +public: + DeclIDIterator() : iterator_adaptor_base(nullptr) {} + + DeclIDIterator(const GlobalDeclID *ID) : iterator_adaptor_base(ID) {} + + value_type operator*() const { return DeclID(*I); } + + bool operator==(const DeclIDIterator &RHS) const { return I == RHS.I; } +}; + +} // namespace clang + +#endif diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 231bda44a9fc..0c95459a6ab1 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -797,7 +797,7 @@ protected: /// /// The first value in the array is the number of specializations/partial /// specializations that follow. - Decl::DeclID *LazySpecializations = nullptr; + DeclID *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index eee8d6b6c6ef..d0ee8ce6365a 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -99,7 +99,7 @@ public: /// passes back decl sets as VisibleDeclaration objects. /// /// The default implementation of this method is a no-op. - virtual Decl *GetExternalDecl(Decl::DeclID ID); + virtual Decl *GetExternalDecl(DeclID ID); /// Resolve a selector ID into a selector. /// @@ -579,7 +579,7 @@ using LazyDeclStmtPtr = /// A lazy pointer to a declaration. using LazyDeclPtr = - LazyOffsetPtr; + LazyOffsetPtr; /// A lazy pointer to a set of CXXCtorInitializers. using LazyCXXCtorInitializersPtr = diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index a2c1b25dd224..163e87cd3df3 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -241,7 +241,7 @@ private: /// A list of the serialization ID numbers for each of the top-level /// declarations parsed within the precompiled preamble. - std::vector TopLevelDeclsInPreamble; + std::vector TopLevelDeclsInPreamble; /// Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults : 1; diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h b/clang/include/clang/Frontend/MultiplexConsumer.h index 7f8d2858b386..6a82c0dd8cec 100644 --- a/clang/include/clang/Frontend/MultiplexConsumer.h +++ b/clang/include/clang/Frontend/MultiplexConsumer.h @@ -35,7 +35,7 @@ public: void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; void MacroRead(serialization::MacroID ID, MacroInfo *MI) override; void TypeRead(serialization::TypeIdx Idx, QualType T) override; - void DeclRead(serialization::DeclID ID, const Decl *D) override; + void DeclRead(DeclID ID, const Decl *D) override; void SelectorRead(serialization::SelectorID iD, Selector Sel) override; void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD) override; diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index 993c9b1daa30..da3204863a41 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -65,7 +65,7 @@ public: /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. - Decl *GetExternalDecl(Decl::DeclID ID) override; + Decl *GetExternalDecl(DeclID ID) override; /// Complete the redeclaration chain if it's been extended since the /// previous generation of the AST source. diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index dcfa4ac0c196..42e09a2bf634 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -17,6 +17,7 @@ #ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H #define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H +#include "clang/AST/DeclID.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" #include "clang/Basic/IdentifierTable.h" @@ -59,92 +60,6 @@ const unsigned VERSION_MINOR = 1; /// and start at 1. 0 is reserved for NULL. using IdentifierID = uint32_t; -/// An ID number that refers to a declaration in an AST file. -/// -/// The ID numbers of declarations are consecutive (in order of -/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. -/// At the start of a chain of precompiled headers, declaration ID 1 is -/// used for the translation unit declaration. -/// -/// FIXME: Merge with Decl::DeclID -using DeclID = uint32_t; - -class LocalDeclID { -public: - explicit LocalDeclID(DeclID ID) : ID(ID) {} - - DeclID get() const { return ID; } - -private: - DeclID ID; -}; - -/// Wrapper class for DeclID. This is helpful to not mix the use of LocalDeclID -/// and GlobalDeclID to improve the type safety. -class GlobalDeclID { -public: - GlobalDeclID() : ID(0) {} - explicit GlobalDeclID(DeclID ID) : ID(ID) {} - - DeclID get() const { return ID; } - - explicit operator DeclID() const { return ID; } - - friend bool operator==(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { - return LHS.ID == RHS.ID; - } - friend bool operator!=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { - return LHS.ID != RHS.ID; - } - // We may sort the global decl ID. - friend bool operator<(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { - return LHS.ID < RHS.ID; - } - friend bool operator>(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { - return LHS.ID > RHS.ID; - } - friend bool operator<=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { - return LHS.ID <= RHS.ID; - } - friend bool operator>=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { - return LHS.ID >= RHS.ID; - } - -private: - DeclID ID; -}; - -/// A helper iterator adaptor to convert the iterators to `SmallVector` -/// to the iterators to `SmallVector`. -class GlobalDeclIDIterator - : public llvm::iterator_adaptor_base { -public: - GlobalDeclIDIterator() : iterator_adaptor_base(nullptr) {} - - GlobalDeclIDIterator(const DeclID *ID) : iterator_adaptor_base(ID) {} - - value_type operator*() const { return GlobalDeclID(*I); } - - bool operator==(const GlobalDeclIDIterator &RHS) const { return I == RHS.I; } -}; - -/// A helper iterator adaptor to convert the iterators to -/// `SmallVector` to the iterators to `SmallVector`. -class DeclIDIterator - : public llvm::iterator_adaptor_base { -public: - DeclIDIterator() : iterator_adaptor_base(nullptr) {} - - DeclIDIterator(const GlobalDeclID *ID) : iterator_adaptor_base(ID) {} - - value_type operator*() const { return DeclID(*I); } - - bool operator==(const DeclIDIterator &RHS) const { return I == RHS.I; } -}; - /// An ID number that refers to a type in an AST file. /// /// The ID of a type is partitioned into two parts: the lower @@ -1238,74 +1153,6 @@ enum SpecialTypeIDs { /// The number of special type IDs. const unsigned NumSpecialTypeIDs = 8; -/// Predefined declaration IDs. -/// -/// These declaration IDs correspond to predefined declarations in the AST -/// context, such as the NULL declaration ID. Such declarations are never -/// actually serialized, since they will be built by the AST context when -/// it is created. -enum PredefinedDeclIDs { - /// The NULL declaration. - PREDEF_DECL_NULL_ID = 0, - - /// The translation unit. - PREDEF_DECL_TRANSLATION_UNIT_ID = 1, - - /// The Objective-C 'id' type. - PREDEF_DECL_OBJC_ID_ID = 2, - - /// The Objective-C 'SEL' type. - PREDEF_DECL_OBJC_SEL_ID = 3, - - /// The Objective-C 'Class' type. - PREDEF_DECL_OBJC_CLASS_ID = 4, - - /// The Objective-C 'Protocol' type. - PREDEF_DECL_OBJC_PROTOCOL_ID = 5, - - /// The signed 128-bit integer type. - PREDEF_DECL_INT_128_ID = 6, - - /// The unsigned 128-bit integer type. - PREDEF_DECL_UNSIGNED_INT_128_ID = 7, - - /// The internal 'instancetype' typedef. - PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8, - - /// The internal '__builtin_va_list' typedef. - PREDEF_DECL_BUILTIN_VA_LIST_ID = 9, - - /// The internal '__va_list_tag' struct, if any. - PREDEF_DECL_VA_LIST_TAG = 10, - - /// The internal '__builtin_ms_va_list' typedef. - PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11, - - /// The predeclared '_GUID' struct. - PREDEF_DECL_BUILTIN_MS_GUID_ID = 12, - - /// The extern "C" context. - PREDEF_DECL_EXTERN_C_CONTEXT_ID = 13, - - /// The internal '__make_integer_seq' template. - PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 14, - - /// The internal '__NSConstantString' typedef. - PREDEF_DECL_CF_CONSTANT_STRING_ID = 15, - - /// The internal '__NSConstantString' tag type. - PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 16, - - /// The internal '__type_pack_element' template. - PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17, -}; - -/// The number of declaration IDs that are predefined. -/// -/// For more information about predefined declarations, see the -/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. -const unsigned int NUM_PREDEF_DECL_IDS = 18; - /// Record of updates for a declaration that was modified after /// being deserialized. This can occur within DECLTYPES_BLOCK_ID. const unsigned int DECL_UPDATES = 49; @@ -2231,9 +2078,9 @@ template <> struct DenseMapInfo { } }; -template <> struct DenseMapInfo { - using DeclID = clang::serialization::DeclID; - using GlobalDeclID = clang::serialization::GlobalDeclID; +template <> struct DenseMapInfo { + using DeclID = clang::DeclID; + using GlobalDeclID = clang::GlobalDeclID; static GlobalDeclID getEmptyKey() { return GlobalDeclID(DenseMapInfo::getEmptyKey()); diff --git a/clang/include/clang/Serialization/ASTDeserializationListener.h b/clang/include/clang/Serialization/ASTDeserializationListener.h index f3a01a4b9731..bb039558f7f7 100644 --- a/clang/include/clang/Serialization/ASTDeserializationListener.h +++ b/clang/include/clang/Serialization/ASTDeserializationListener.h @@ -44,7 +44,7 @@ public: /// unqualified. virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { } /// A decl was deserialized from the AST file. - virtual void DeclRead(serialization::DeclID ID, const Decl *D) { } + virtual void DeclRead(DeclID ID, const Decl *D) {} /// A selector was read from the AST file. virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {} /// A macro definition was read from the AST file. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index ed917aa16422..65e2bcb990c3 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -501,10 +501,7 @@ private: /// = I + 1 has already been loaded. llvm::PagedVector DeclsLoaded; - static_assert(std::is_same_v); - - using GlobalDeclMapType = - ContinuousRangeMap; + using GlobalDeclMapType = ContinuousRangeMap; /// Mapping from global declaration IDs to the module in which the /// declaration resides. @@ -512,16 +509,15 @@ private: using FileOffset = std::pair; using FileOffsetsTy = SmallVector; - using DeclUpdateOffsetsMap = - llvm::DenseMap; + using DeclUpdateOffsetsMap = llvm::DenseMap; /// Declarations that have modifications residing in a later file /// in the chain. DeclUpdateOffsetsMap DeclUpdateOffsets; - using DelayedNamespaceOffsetMapTy = llvm::DenseMap< - serialization::GlobalDeclID, - std::pair>; + using DelayedNamespaceOffsetMapTy = + llvm::DenseMap>; /// Mapping from global declaration IDs to the lexical and visible block /// offset for delayed namespace in reduced BMI. @@ -535,13 +531,12 @@ private: struct PendingUpdateRecord { Decl *D; - serialization::GlobalDeclID ID; + GlobalDeclID ID; // Whether the declaration was just deserialized. bool JustLoaded; - PendingUpdateRecord(serialization::GlobalDeclID ID, Decl *D, - bool JustLoaded) + PendingUpdateRecord(GlobalDeclID ID, Decl *D, bool JustLoaded) : D(D), ID(ID), JustLoaded(JustLoaded) {} }; @@ -594,10 +589,10 @@ private: struct FileDeclsInfo { ModuleFile *Mod = nullptr; - ArrayRef Decls; + ArrayRef Decls; FileDeclsInfo() = default; - FileDeclsInfo(ModuleFile *Mod, ArrayRef Decls) + FileDeclsInfo(ModuleFile *Mod, ArrayRef Decls) : Mod(Mod), Decls(Decls) {} }; @@ -608,8 +603,7 @@ private: /// Decl::Kind, DeclID pairs. using unalighed_decl_id_t = llvm::support::detail::packed_endian_specific_integral< - serialization::DeclID, llvm::endianness::native, - llvm::support::unaligned>; + DeclID, llvm::endianness::native, llvm::support::unaligned>; using LexicalContents = ArrayRef; /// Map from a DeclContext to its lexical contents. @@ -635,8 +629,7 @@ private: /// Updates to the visible declarations of declaration contexts that /// haven't been loaded yet. - llvm::DenseMap - PendingVisibleUpdates; + llvm::DenseMap PendingVisibleUpdates; /// The set of C++ or Objective-C classes that have forward /// declarations that have not yet been linked to their definitions. @@ -662,8 +655,7 @@ private: /// Read the record that describes the visible contents of a DC. bool ReadVisibleDeclContextStorage(ModuleFile &M, llvm::BitstreamCursor &Cursor, - uint64_t Offset, - serialization::GlobalDeclID ID); + uint64_t Offset, GlobalDeclID ID); /// A vector containing identifiers that have already been /// loaded. @@ -816,14 +808,14 @@ private: /// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks /// in the chain. The referenced declarations are deserialized and passed to /// the consumer eagerly. - SmallVector EagerlyDeserializedDecls; + SmallVector EagerlyDeserializedDecls; /// The IDs of all tentative definitions stored in the chain. /// /// Sema keeps track of all tentative definitions in a TU because it has to /// complete them and pass them on to CodeGen. Thus, tentative definitions in /// the PCH chain must be eagerly deserialized. - SmallVector TentativeDefinitions; + SmallVector TentativeDefinitions; /// The IDs of all CXXRecordDecls stored in the chain whose VTables are /// used. @@ -831,7 +823,7 @@ private: /// CodeGen has to emit VTables for these records, so they have to be eagerly /// deserialized. struct VTableUse { - serialization::GlobalDeclID ID; + GlobalDeclID ID; SourceLocation::UIntTy RawLoc; bool Used; }; @@ -844,7 +836,7 @@ private: /// instantiation where the first value is the ID of the decl and the second /// is the instantiation location. struct PendingInstantiation { - serialization::GlobalDeclID ID; + GlobalDeclID ID; SourceLocation::UIntTy RawLoc; }; SmallVector PendingInstantiations; @@ -857,11 +849,11 @@ private: /// A snapshot of Sema's unused file-scoped variable tracking, for /// generating warnings. - SmallVector UnusedFileScopedDecls; + SmallVector UnusedFileScopedDecls; /// A list of all the delegating constructors we've seen, to diagnose /// cycles. - SmallVector DelegatingCtorDecls; + SmallVector DelegatingCtorDecls; /// Method selectors used in a @selector expression. Used for /// implementation of -Wselector. @@ -874,7 +866,7 @@ private: /// The IDs of type aliases for ext_vectors that exist in the chain. /// /// Used by Sema for finding sugared names for ext_vectors in diagnostics. - SmallVector ExtVectorDecls; + SmallVector ExtVectorDecls; //@} @@ -885,7 +877,7 @@ private: /// The IDs of all potentially unused typedef names in the chain. /// /// Sema tracks these to emit warnings. - SmallVector UnusedLocalTypedefNameCandidates; + SmallVector UnusedLocalTypedefNameCandidates; /// Our current depth in #pragma cuda force_host_device begin/end /// macros. @@ -894,7 +886,7 @@ private: /// The IDs of the declarations Sema stores directly. /// /// Sema tracks a few important decls, such as namespace std, directly. - SmallVector SemaDeclRefs; + SmallVector SemaDeclRefs; /// The IDs of the types ASTContext stores directly. /// @@ -905,7 +897,7 @@ private: /// /// The AST context tracks a few important decls, currently cudaConfigureCall, /// directly. - SmallVector CUDASpecialDeclRefs; + SmallVector CUDASpecialDeclRefs; /// The floating point pragma option settings. SmallVector FPPragmaOptions; @@ -954,12 +946,12 @@ private: llvm::DenseMap> OpenCLDeclExtMap; /// A list of the namespaces we've seen. - SmallVector KnownNamespaces; + SmallVector KnownNamespaces; /// A list of undefined decls with internal linkage followed by the /// SourceLocation of a matching ODR-use. struct UndefinedButUsedDecl { - serialization::GlobalDeclID ID; + GlobalDeclID ID; SourceLocation::UIntTy RawLoc; }; SmallVector UndefinedButUsed; @@ -974,8 +966,7 @@ private: /// The IDs of all decls to be checked for deferred diags. /// /// Sema tracks these to emit deferred diags. - llvm::SmallSetVector - DeclsToCheckForDeferredDiags; + llvm::SmallSetVector DeclsToCheckForDeferredDiags; private: struct ImportedSubmodule { @@ -1112,7 +1103,7 @@ private: /// /// The declarations on the identifier chain for these identifiers will be /// loaded once the recursive loading has completed. - llvm::MapVector> + llvm::MapVector> PendingIdentifierInfos; /// The set of lookup results that we have faked in order to support @@ -1157,8 +1148,8 @@ private: /// been loaded but its DeclContext was not set yet. struct PendingDeclContextInfo { Decl *D; - serialization::GlobalDeclID SemaDC; - serialization::GlobalDeclID LexicalDC; + GlobalDeclID SemaDC; + GlobalDeclID LexicalDC; }; /// The set of Decls that have been loaded but their DeclContexts are @@ -1239,8 +1230,7 @@ private: /// module is loaded. SmallVector ObjCClassesLoaded; - using KeyDeclsMap = - llvm::DenseMap>; + using KeyDeclsMap = llvm::DenseMap>; /// A mapping from canonical declarations to the set of global /// declaration IDs for key declaration that have been merged with that @@ -1449,7 +1439,7 @@ private: QualType readTypeRecord(unsigned Index); RecordLocation TypeCursorForIndex(unsigned Index); void LoadedDecl(unsigned Index, Decl *D); - Decl *ReadDeclRecord(serialization::GlobalDeclID ID); + Decl *ReadDeclRecord(GlobalDeclID ID); void markIncompleteDeclChain(Decl *D); /// Returns the most recent declaration of a declaration (which must be @@ -1457,11 +1447,10 @@ private: /// merged into its redecl chain. Decl *getMostRecentExistingDecl(Decl *D); - RecordLocation DeclCursorForID(serialization::GlobalDeclID ID, - SourceLocation &Location); + RecordLocation DeclCursorForID(GlobalDeclID ID, SourceLocation &Location); void loadDeclUpdateRecords(PendingUpdateRecord &Record); void loadPendingDeclChain(Decl *D, uint64_t LocalOffset); - void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D, + void loadObjCCategories(GlobalDeclID ID, ObjCInterfaceDecl *D, unsigned PreviousGeneration = 0); RecordLocation getLocalBitOffset(uint64_t GlobalOffset); @@ -1496,11 +1485,10 @@ private: unsigned ClientLoadCapabilities); public: - class ModuleDeclIterator - : public llvm::iterator_adaptor_base< - ModuleDeclIterator, const serialization::LocalDeclID *, - std::random_access_iterator_tag, const Decl *, ptrdiff_t, - const Decl *, const Decl *> { + class ModuleDeclIterator : public llvm::iterator_adaptor_base< + ModuleDeclIterator, const LocalDeclID *, + std::random_access_iterator_tag, const Decl *, + ptrdiff_t, const Decl *, const Decl *> { ASTReader *Reader = nullptr; ModuleFile *Mod = nullptr; @@ -1508,7 +1496,7 @@ public: ModuleDeclIterator() : iterator_adaptor_base(nullptr) {} ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, - const serialization::LocalDeclID *Pos) + const LocalDeclID *Pos) : iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {} value_type operator*() const { @@ -1536,9 +1524,8 @@ private: void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name); - void addPendingDeclContextInfo(Decl *D, - serialization::GlobalDeclID SemaDC, - serialization::GlobalDeclID LexicalDC) { + void addPendingDeclContextInfo(Decl *D, GlobalDeclID SemaDC, + GlobalDeclID LexicalDC) { assert(D); PendingDeclContextInfo Info = { D, SemaDC, LexicalDC }; PendingDeclContextInfos.push_back(Info); @@ -1916,38 +1903,36 @@ public: /// Map from a local declaration ID within a given module to a /// global declaration ID. - serialization::GlobalDeclID - getGlobalDeclID(ModuleFile &F, serialization::LocalDeclID LocalID) const; + GlobalDeclID getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const; /// Returns true if global DeclID \p ID originated from module \p M. - bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const; + bool isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const; /// Retrieve the module file that owns the given declaration, or NULL /// if the declaration is not from a module file. ModuleFile *getOwningModuleFile(const Decl *D); /// Returns the source location for the decl \p ID. - SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID); + SourceLocation getSourceLocationForDeclID(GlobalDeclID ID); /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. - Decl *GetDecl(serialization::GlobalDeclID ID); - Decl *GetExternalDecl(Decl::DeclID ID) override; + Decl *GetDecl(GlobalDeclID ID); + Decl *GetExternalDecl(DeclID ID) override; /// Resolve a declaration ID into a declaration. Return 0 if it's not /// been loaded yet. - Decl *GetExistingDecl(serialization::GlobalDeclID ID); + Decl *GetExistingDecl(GlobalDeclID ID); /// Reads a declaration with the given local ID in the given module. - Decl *GetLocalDecl(ModuleFile &F, serialization::LocalDeclID LocalID) { + Decl *GetLocalDecl(ModuleFile &F, LocalDeclID LocalID) { return GetDecl(getGlobalDeclID(F, LocalID)); } /// Reads a declaration with the given local ID in the given module. /// /// \returns The requested declaration, casted to the given return type. - template - T *GetLocalDeclAs(ModuleFile &F, serialization::LocalDeclID LocalID) { + template T *GetLocalDeclAs(ModuleFile &F, LocalDeclID LocalID) { return cast_or_null(GetLocalDecl(F, LocalID)); } @@ -1956,16 +1941,14 @@ public: /// /// \returns the global ID of the given declaration as known in the given /// module file. - serialization::DeclID - mapGlobalIDToModuleFileGlobalID(ModuleFile &M, - serialization::GlobalDeclID GlobalID); + DeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M, GlobalDeclID GlobalID); /// Reads a declaration ID from the given position in a record in the /// given module. /// /// \returns The declaration ID read from the record, adjusted to a global ID. - serialization::GlobalDeclID - ReadDeclID(ModuleFile &F, const RecordData &Record, unsigned &Idx); + GlobalDeclID ReadDeclID(ModuleFile &F, const RecordData &Record, + unsigned &Idx); /// Reads a declaration from the given position in a record in the /// given module. @@ -2139,10 +2122,9 @@ public: void LoadSelector(Selector Sel); void SetIdentifierInfo(unsigned ID, IdentifierInfo *II); - void SetGloballyVisibleDecls( - IdentifierInfo *II, - const SmallVectorImpl &DeclIDs, - SmallVectorImpl *Decls = nullptr); + void SetGloballyVisibleDecls(IdentifierInfo *II, + const SmallVectorImpl &DeclIDs, + SmallVectorImpl *Decls = nullptr); /// Report a diagnostic. DiagnosticBuilder Diag(unsigned DiagID) const; @@ -2383,7 +2365,7 @@ public: // Contains the IDs for declarations that were requested before we have // access to a Sema object. - SmallVector PreloadedDeclIDs; + SmallVector PreloadedDeclIDs; /// Retrieve the semantic analysis object used to analyze the /// translation unit in which the precompiled header is being diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h index 9eaf50a76d52..06b80f266a94 100644 --- a/clang/include/clang/Serialization/ASTRecordReader.h +++ b/clang/include/clang/Serialization/ASTRecordReader.h @@ -136,7 +136,7 @@ public: /// Reads a declaration with the given local ID in the given module. /// /// \returns The requested declaration, casted to the given return type. - template T *GetLocalDeclAs(serialization::LocalDeclID LocalID) { + template T *GetLocalDeclAs(LocalDeclID LocalID) { return cast_or_null(Reader->GetLocalDecl(*F, LocalID)); } @@ -182,9 +182,7 @@ public: /// Reads a declaration ID from the given position in this record. /// /// \returns The declaration ID read from the record, adjusted to a global ID. - serialization::GlobalDeclID readDeclID() { - return Reader->ReadDeclID(*F, Record, Idx); - } + GlobalDeclID readDeclID() { return Reader->ReadDeclID(*F, Record, Idx); } /// Reads a declaration from the given position in a record in the /// given module, advancing Idx. diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 13b4ad4ad295..d01b31549248 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -212,10 +212,10 @@ private: llvm::SmallVector DelayedNamespace; /// The first ID number we can use for our own declarations. - serialization::DeclID FirstDeclID = serialization::NUM_PREDEF_DECL_IDS; + DeclID FirstDeclID = clang::NUM_PREDEF_DECL_IDS; /// The decl ID that will be assigned to the next new decl. - serialization::DeclID NextDeclID = FirstDeclID; + DeclID NextDeclID = FirstDeclID; /// Map that provides the ID numbers of each declaration within /// the output stream, as well as those deserialized from a chained PCH. @@ -223,7 +223,7 @@ private: /// The ID numbers of declarations are consecutive (in order of /// discovery) and start at 2. 1 is reserved for the translation /// unit, while 0 is reserved for NULL. - llvm::DenseMap DeclIDs; + llvm::DenseMap DeclIDs; /// Offset of each declaration in the bitstream, indexed by /// the declaration's ID. @@ -234,8 +234,7 @@ private: uint64_t DeclTypesBlockStartOffset = 0; /// Sorted (by file offset) vector of pairs of file offset/DeclID. - using LocDeclIDsTy = - SmallVector, 64>; + using LocDeclIDsTy = SmallVector, 64>; struct DeclIDInFileInfo { LocDeclIDsTy DeclIDs; @@ -250,7 +249,7 @@ private: /// that it contains. FileDeclIDsTy FileDeclIDs; - void associateDeclWithFile(const Decl *D, serialization::DeclID); + void associateDeclWithFile(const Decl *D, DeclID); /// The first ID number we can use for our own types. serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS; @@ -421,8 +420,8 @@ private: /// headers. The declarations themselves are stored as declaration /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS /// record. - SmallVector EagerlyDeserializedDecls; - SmallVector ModularCodegenDecls; + SmallVector EagerlyDeserializedDecls; + SmallVector ModularCodegenDecls; /// DeclContexts that have received extensions since their serialized /// form. @@ -708,8 +707,7 @@ public: if (D->isFromASTFile()) return false; auto I = DeclIDs.find(D); - return (I == DeclIDs.end() || - I->second >= serialization::NUM_PREDEF_DECL_IDS); + return (I == DeclIDs.end() || I->second >= clang::NUM_PREDEF_DECL_IDS); }; /// Emit a reference to a declaration. @@ -718,11 +716,11 @@ public: void AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record); /// Force a declaration to be emitted and get its ID. - serialization::DeclID GetDeclRef(const Decl *D); + DeclID GetDeclRef(const Decl *D); /// Determine the declaration ID of an already-emitted /// declaration. - serialization::DeclID getDeclID(const Decl *D); + DeclID getDeclID(const Decl *D); /// Whether or not the declaration got emitted. If not, it wouldn't be /// emitted. diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 492c35dceb08..1f7222655876 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -459,10 +459,10 @@ public: const DeclOffset *DeclOffsets = nullptr; /// Base declaration ID for declarations local to this module. - serialization::DeclID BaseDeclID = 0; + DeclID BaseDeclID = 0; /// Remapping table for declaration IDs in this module. - ContinuousRangeMap DeclRemap; + ContinuousRangeMap DeclRemap; /// Mapping from the module files that this module file depends on /// to the base declaration ID for that module as it is understood within this @@ -471,10 +471,10 @@ public: /// This is effectively a reverse global-to-local mapping for declaration /// IDs, so that we can interpret a true global ID (for this translation unit) /// as a local ID (for this module file). - llvm::DenseMap GlobalToLocalDeclIDs; + llvm::DenseMap GlobalToLocalDeclIDs; /// Array of file-level DeclIDs sorted by file. - const serialization::LocalDeclID *FileSortedDecls = nullptr; + const LocalDeclID *FileSortedDecls = nullptr; unsigned NumFileSortedDecls = 0; /// Array of category list location information within this diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 0f894c623bee..a7386f755ca0 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1083,8 +1083,7 @@ void ASTContext::addModuleInitializer(Module *M, Decl *D) { Inits->Initializers.push_back(D); } -void ASTContext::addLazyModuleInitializers(Module *M, - ArrayRef IDs) { +void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef IDs) { auto *&Inits = ModuleInitializers[M]; if (!Inits) Inits = new (*this) PerModuleInitializers; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 474e0ccde5bb..f452902110c7 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2151,7 +2151,7 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartL, return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S); } -VarDecl *VarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +VarDecl *VarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None); @@ -2929,7 +2929,7 @@ QualType ParmVarDecl::getOriginalType() const { return T; } -ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None, nullptr); @@ -4553,7 +4553,7 @@ FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC, BW, Mutable, InitStyle); } -FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, nullptr, false, ICIS_NoInit); @@ -4863,7 +4863,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, return Enum; } -EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, DeclID ID) { EnumDecl *Enum = new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr, false, false, false); @@ -5025,7 +5025,7 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, return R; } -RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID) { +RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, DeclID ID) { RecordDecl *R = new (C, ID) RecordDecl(Record, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -5297,7 +5297,7 @@ PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, } PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, + DeclID ID, unsigned ArgSize) { return new (C, ID, additionalSizeToAlloc(ArgSize + 1)) PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown); @@ -5322,7 +5322,7 @@ PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC, } PragmaDetectMismatchDecl * -PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NameValueSize) { return new (C, ID, additionalSizeToAlloc(NameValueSize + 1)) PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0); @@ -5349,7 +5349,7 @@ LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL); } -LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation()); } @@ -5390,7 +5390,7 @@ ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, QualType Type, } ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other); } @@ -5408,7 +5408,7 @@ FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, return New; } -FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) FunctionDecl( Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -5418,7 +5418,7 @@ BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) BlockDecl(DC, L); } -BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) BlockDecl(nullptr, SourceLocation()); } @@ -5432,7 +5432,7 @@ CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC, CapturedDecl(DC, NumParams); } -CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumParams) { return new (C, ID, additionalSizeToAlloc(NumParams)) CapturedDecl(nullptr, NumParams); @@ -5458,8 +5458,8 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, return new (C, CD) EnumConstantDecl(C, CD, L, Id, T, E, V); } -EnumConstantDecl * -EnumConstantDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +EnumConstantDecl *EnumConstantDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) EnumConstantDecl(C, nullptr, SourceLocation(), nullptr, QualType(), nullptr, llvm::APSInt()); } @@ -5486,7 +5486,7 @@ IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) IndirectFieldDecl(C, nullptr, SourceLocation(), DeclarationName(), QualType(), std::nullopt); @@ -5547,7 +5547,7 @@ bool TypedefNameDecl::isTransparentTagSlow() const { return isTransparent; } -TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5560,7 +5560,7 @@ TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo); } -TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5591,7 +5591,7 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, } FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -5609,7 +5609,7 @@ TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) { } TopLevelStmtDecl *TopLevelStmtDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) TopLevelStmtDecl(/*DC=*/nullptr, SourceLocation(), /*S=*/nullptr); } @@ -5630,7 +5630,7 @@ EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) EmptyDecl(DC, L); } -EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) EmptyDecl(nullptr, SourceLocation()); } @@ -5663,7 +5663,7 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C, return Result; } -HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr, SourceLocation(), SourceLocation()); } @@ -5719,7 +5719,7 @@ ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC, return Import; } -ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumLocations) { return new (C, ID, additionalSizeToAlloc(NumLocations)) ImportDecl(EmptyShell()); @@ -5752,6 +5752,6 @@ ExportDecl *ExportDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) ExportDecl(DC, ExportLoc); } -ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ExportDecl(nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 7cb6b31c541f..a2d88cf7a6a1 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -70,8 +70,8 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const { #define ABSTRACT_DECL(DECL) #include "clang/AST/DeclNodes.inc" -void *Decl::operator new(std::size_t Size, const ASTContext &Context, - Decl::DeclID ID, std::size_t Extra) { +void *Decl::operator new(std::size_t Size, const ASTContext &Context, DeclID ID, + std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. static_assert(sizeof(unsigned) * 2 >= alignof(Decl), diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 426c52620510..c525c3368ce2 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -57,7 +57,7 @@ using namespace clang; void AccessSpecDecl::anchor() {} -AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) AccessSpecDecl(EmptyShell()); } @@ -160,8 +160,8 @@ CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, return R; } -CXXRecordDecl * -CXXRecordDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID) { +CXXRecordDecl *CXXRecordDecl::CreateDeserialized(const ASTContext &C, + DeclID ID) { auto *R = new (C, ID) CXXRecordDecl(CXXRecord, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -2163,7 +2163,7 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( } CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) CXXDeductionGuideDecl( C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), QualType(), nullptr, SourceLocation(), nullptr, @@ -2176,7 +2176,7 @@ RequiresExprBodyDecl *RequiresExprBodyDecl::Create( } RequiresExprBodyDecl *RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) RequiresExprBodyDecl(C, nullptr, SourceLocation()); } @@ -2281,7 +2281,7 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, isInline, ConstexprKind, EndLocation, TrailingRequiresClause); } -CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) CXXMethodDecl( CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, @@ -2699,7 +2699,7 @@ CXXConstructorDecl::CXXConstructorDecl( void CXXConstructorDecl::anchor() {} CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, + DeclID ID, uint64_t AllocKind) { bool hasTrailingExplicit = static_cast(AllocKind & TAKHasTailExplicit); bool isInheritingConstructor = @@ -2845,8 +2845,8 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const { void CXXDestructorDecl::anchor() {} -CXXDestructorDecl * -CXXDestructorDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +CXXDestructorDecl *CXXDestructorDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) CXXDestructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -2877,8 +2877,8 @@ void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) { void CXXConversionDecl::anchor() {} -CXXConversionDecl * -CXXConversionDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +CXXConversionDecl *CXXConversionDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) CXXConversionDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified, @@ -2923,8 +2923,7 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces); } -LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(), SourceLocation(), LinkageSpecLanguageIDs::C, false); @@ -2946,7 +2945,7 @@ UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, } UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), @@ -2985,7 +2984,7 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, PrevDecl, Nested); } -NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(), SourceLocation(), nullptr, nullptr, false); } @@ -3046,8 +3045,8 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, QualifierLoc, IdentLoc, Namespace); } -NamespaceAliasDecl * -NamespaceAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +NamespaceAliasDecl *NamespaceAliasDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, NestedNameSpecifierLoc(), @@ -3102,8 +3101,7 @@ UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty) : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()), redeclarable_base(C) {} -UsingShadowDecl * -UsingShadowDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UsingShadowDecl *UsingShadowDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell()); } @@ -3126,7 +3124,7 @@ ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC, } ConstructorUsingShadowDecl * -ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell()); } @@ -3174,7 +3172,7 @@ UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL, return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename); } -UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UsingDecl(nullptr, SourceLocation(), NestedNameSpecifierLoc(), DeclarationNameInfo(), false); @@ -3198,7 +3196,7 @@ UsingEnumDecl *UsingEnumDecl::Create(ASTContext &C, DeclContext *DC, UsingEnumDecl(DC, EnumType->getType()->getAsTagDecl()->getDeclName(), UL, EL, NL, EnumType); } -UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UsingEnumDecl(nullptr, DeclarationName(), SourceLocation(), SourceLocation(), SourceLocation(), nullptr); @@ -3217,7 +3215,7 @@ UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls); } -UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumExpansions) { size_t Extra = additionalSizeToAlloc(NumExpansions); auto *Result = @@ -3243,7 +3241,7 @@ UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingValueDecl * -UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(), SourceLocation(), NestedNameSpecifierLoc(), @@ -3273,7 +3271,7 @@ UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingTypenameDecl * -UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UnresolvedUsingTypenameDecl( nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), nullptr, SourceLocation()); @@ -3286,7 +3284,7 @@ UnresolvedUsingIfExistsDecl::Create(ASTContext &Ctx, DeclContext *DC, } UnresolvedUsingIfExistsDecl * -UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, Decl::DeclID ID) { +UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, DeclID ID) { return new (Ctx, ID) UnresolvedUsingIfExistsDecl(nullptr, SourceLocation(), DeclarationName()); } @@ -3310,7 +3308,7 @@ StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, } StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), false); } @@ -3332,7 +3330,7 @@ BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) BindingDecl(DC, IdLoc, Id); } -BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); } @@ -3363,7 +3361,7 @@ DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, } DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, + DeclID ID, unsigned NumBindings) { size_t Extra = additionalSizeToAlloc(NumBindings); auto *Result = new (C, ID, Extra) @@ -3401,8 +3399,7 @@ MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) MSPropertyDecl(DC, L, N, T, TInfo, StartL, Getter, Setter); } -MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(), DeclarationName(), QualType(), nullptr, SourceLocation(), nullptr, nullptr); @@ -3419,7 +3416,7 @@ MSGuidDecl *MSGuidDecl::Create(const ASTContext &C, QualType T, Parts P) { return new (C, DC) MSGuidDecl(DC, T, P); } -MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) MSGuidDecl(nullptr, QualType(), Parts()); } @@ -3529,7 +3526,7 @@ UnnamedGlobalConstantDecl::Create(const ASTContext &C, QualType T, } UnnamedGlobalConstantDecl * -UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UnnamedGlobalConstantDecl(C, nullptr, QualType(), APValue()); } diff --git a/clang/lib/AST/DeclFriend.cpp b/clang/lib/AST/DeclFriend.cpp index 1fabf8aa80c2..f6d11e550b57 100644 --- a/clang/lib/AST/DeclFriend.cpp +++ b/clang/lib/AST/DeclFriend.cpp @@ -62,7 +62,7 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, return FD; } -FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned FriendTypeNumTPLists) { std::size_t Extra = additionalSizeToAlloc(FriendTypeNumTPLists); diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index d4275eea0582..f98ec6727e48 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -862,7 +862,7 @@ ObjCMethodDecl *ObjCMethodDecl::Create( isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); } -ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(), Selector(), QualType(), nullptr, nullptr); } @@ -1486,7 +1486,7 @@ ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc, } ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx, - Decl::DeclID ID) { + DeclID ID) { return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr, ObjCTypeParamVariance::Invariant, SourceLocation(), 0, SourceLocation(), @@ -1551,7 +1551,7 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create( } ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { auto *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), nullptr, false); @@ -1865,7 +1865,7 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, synthesized); } -ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, ObjCIvarDecl::None, nullptr, false); @@ -1914,7 +1914,7 @@ ObjCAtDefsFieldDecl } ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr); @@ -1949,7 +1949,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, } ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { ObjCProtocolDecl *Result = new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(), SourceLocation(), nullptr); @@ -2148,7 +2148,7 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create( } ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(), SourceLocation(), SourceLocation(), nullptr, nullptr, nullptr); @@ -2189,7 +2189,7 @@ ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create( } ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation(), SourceLocation()); @@ -2296,7 +2296,7 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, } ObjCImplementationDecl * -ObjCImplementationDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ObjCImplementationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -2339,7 +2339,7 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, } ObjCCompatibleAliasDecl * -ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(), nullptr, nullptr); } @@ -2360,7 +2360,7 @@ ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr, SourceLocation(), SourceLocation(), QualType(), nullptr, None); @@ -2393,7 +2393,7 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, } ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, Dynamic, nullptr, SourceLocation()); diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp index b178a15aab5f..9f1d2bd41235 100644 --- a/clang/lib/AST/DeclOpenMP.cpp +++ b/clang/lib/AST/DeclOpenMP.cpp @@ -35,9 +35,8 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C, return D; } -OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, - unsigned N) { +OMPThreadPrivateDecl * +OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, 0, N); } @@ -63,7 +62,7 @@ OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC, return D; } -OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NVars, unsigned NClauses) { return OMPDeclarativeDirective::createEmptyDirective( @@ -89,7 +88,7 @@ OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC, L); } -OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 0, SourceLocation()); @@ -117,7 +116,7 @@ OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create( } OMPDeclareReductionDecl * -OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) OMPDeclareReductionDecl( OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(), QualType(), /*PrevDeclInScope=*/nullptr); @@ -147,9 +146,8 @@ OMPDeclareMapperDecl *OMPDeclareMapperDecl::Create( C, DC, Clauses, 1, L, Name, T, VarName, PrevDeclInScope); } -OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, - unsigned N) { +OMPDeclareMapperDecl * +OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 1, SourceLocation(), DeclarationName(), QualType(), DeclarationName(), /*PrevDeclInScope=*/nullptr); @@ -179,7 +177,7 @@ OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC, } OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType(), /*TInfo=*/nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 67bb9e41e3e6..ca998b502bee 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -337,7 +337,7 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); if (CommonBasePtr->LazySpecializations) { ASTContext &Context = getASTContext(); - Decl::DeclID *Specs = CommonBasePtr->LazySpecializations; + DeclID *Specs = CommonBasePtr->LazySpecializations; CommonBasePtr->LazySpecializations = nullptr; for (uint32_t I = 0, N = *Specs++; I != N; ++I) (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); @@ -418,7 +418,7 @@ FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -503,7 +503,7 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC, } ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -652,14 +652,14 @@ TemplateTypeParmDecl *TemplateTypeParmDecl::Create( } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID) { +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, DeclID ID) { return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, false, false, std::nullopt); } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID, +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, DeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc(HasTypeConstraint ? 1 : 0)) @@ -759,7 +759,7 @@ NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc, @@ -770,7 +770,7 @@ NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint) { auto *NTTP = @@ -836,13 +836,13 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, false, nullptr, false, nullptr); } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumExpansions) { auto *TTP = new (C, ID, additionalSizeToAlloc(NumExpansions)) @@ -948,8 +948,7 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, } ClassTemplateSpecializationDecl * -ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { auto *Result = new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); Result->setMayHaveOutOfDateDef(false); @@ -1035,8 +1034,7 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, return TD; } -ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, DeclID ID) { ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); @@ -1070,7 +1068,7 @@ ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( ImplicitConceptSpecializationDecl * ImplicitConceptSpecializationDecl::CreateDeserialized( - const ASTContext &C, Decl::DeclID ID, unsigned NumTemplateArgs) { + const ASTContext &C, DeclID ID, unsigned NumTemplateArgs) { return new (C, ID, additionalSizeToAlloc(NumTemplateArgs)) ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); } @@ -1133,7 +1131,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, ClassTemplatePartialSpecializationDecl * ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); Result->setMayHaveOutOfDateDef(false); return Result; @@ -1160,7 +1158,7 @@ FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, } FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) FriendTemplateDecl(EmptyShell()); } @@ -1180,7 +1178,7 @@ TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1217,8 +1215,7 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, return TD; } -VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1340,7 +1337,7 @@ VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( } VarTemplateSpecializationDecl * -VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) VarTemplateSpecializationDecl(VarTemplateSpecialization, C); } @@ -1432,7 +1429,7 @@ VarTemplatePartialSpecializationDecl::Create( VarTemplatePartialSpecializationDecl * VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + DeclID ID) { return new (C, ID) VarTemplatePartialSpecializationDecl(C); } @@ -1546,7 +1543,7 @@ TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C, } TemplateParamObjectDecl * -TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, DeclID ID) { auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue()); C.addDestruction(&TPOD->Value); return TPOD; diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index 2e54d9f9af1c..26ded22bf329 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -68,7 +68,7 @@ bool ExternalASTSource::layoutRecordType( return false; } -Decl *ExternalASTSource::GetExternalDecl(Decl::DeclID ID) { return nullptr; } +Decl *ExternalASTSource::GetExternalDecl(DeclID ID) { return nullptr; } Selector ExternalASTSource::GetExternalSelector(uint32_t ID) { return Selector(); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 3610a08831e7..361331de145b 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1067,7 +1067,7 @@ public: std::vector takeTopLevelDecls() { return std::move(TopLevelDecls); } - std::vector takeTopLevelDeclIDs() { + std::vector takeTopLevelDeclIDs() { return std::move(TopLevelDeclIDs); } @@ -1101,7 +1101,7 @@ public: private: unsigned Hash = 0; std::vector TopLevelDecls; - std::vector TopLevelDeclIDs; + std::vector TopLevelDeclIDs; llvm::SmallVector PreambleDiags; }; diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index b7c9967316f0..91ce16e5e795 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -80,7 +80,7 @@ public: if (Previous) Previous->TypeRead(Idx, T); } - void DeclRead(serialization::DeclID ID, const Decl *D) override { + void DeclRead(DeclID ID, const Decl *D) override { if (Previous) Previous->DeclRead(ID, D); } @@ -102,7 +102,7 @@ public: bool DeletePrevious) : DelegatingDeserializationListener(Previous, DeletePrevious) {} - void DeclRead(serialization::DeclID ID, const Decl *D) override { + void DeclRead(DeclID ID, const Decl *D) override { llvm::outs() << "PCH DECL: " << D->getDeclKindName(); if (const NamedDecl *ND = dyn_cast(D)) { llvm::outs() << " - "; @@ -128,7 +128,7 @@ public: : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx), NamesToCheck(NamesToCheck) {} - void DeclRead(serialization::DeclID ID, const Decl *D) override { + void DeclRead(DeclID ID, const Decl *D) override { if (const NamedDecl *ND = dyn_cast(D)) if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { unsigned DiagID diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index 744ea70cc24d..9e885c8dc0f6 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -52,8 +52,7 @@ void MultiplexASTDeserializationListener::TypeRead( Listeners[i]->TypeRead(Idx, T); } -void MultiplexASTDeserializationListener::DeclRead( - serialization::DeclID ID, const Decl *D) { +void MultiplexASTDeserializationListener::DeclRead(DeclID ID, const Decl *D) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->DeclRead(ID, D); } diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index 6a5f9f6680e6..e48c72498389 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -46,7 +46,7 @@ void MultiplexExternalSemaSource::AddSource(ExternalSemaSource *Source) { // ExternalASTSource. //===----------------------------------------------------------------------===// -Decl *MultiplexExternalSemaSource::GetExternalDecl(Decl::DeclID ID) { +Decl *MultiplexExternalSemaSource::GetExternalDecl(DeclID ID) { for(size_t i = 0; i < Sources.size(); ++i) if (Decl *Result = Sources[i]->GetExternalDecl(ID)) return Result; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 43b69045bb05..df9984d537bf 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -7668,8 +7668,7 @@ GlobalDeclID ASTReader::getGlobalDeclID(ModuleFile &F, return GlobalDeclID(ID + I->second); } -bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID, - ModuleFile &M) const { +bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const { // Predefined decls aren't from any module. if (ID.get() < NUM_PREDEF_DECL_IDS) return false; @@ -7821,8 +7820,8 @@ DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); ModuleFile *Owner = I->second; - llvm::DenseMap::iterator Pos - = M.GlobalToLocalDeclIDs.find(Owner); + llvm::DenseMap::iterator Pos = + M.GlobalToLocalDeclIDs.find(Owner); if (Pos == M.GlobalToLocalDeclIDs.end()) return 0; @@ -7872,7 +7871,7 @@ void ASTReader::FindExternalLexicalDecls( if (!IsKindWeWant(K)) continue; - auto ID = (serialization::DeclID)+LexicalDecls[I + 1]; + auto ID = (DeclID) + LexicalDecls[I + 1]; // Don't add predefined declarations to the lexical context more // than once. @@ -7954,7 +7953,7 @@ void ASTReader::FindFileRegionDecls(FileID File, SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length); DeclIDComp DIDComp(*this, *DInfo.Mod); - ArrayRef::iterator BeginIt = + ArrayRef::iterator BeginIt = llvm::lower_bound(DInfo.Decls, BeginLoc, DIDComp); if (BeginIt != DInfo.Decls.begin()) --BeginIt; @@ -7967,13 +7966,12 @@ void ASTReader::FindFileRegionDecls(FileID File, ->isTopLevelDeclInObjCContainer()) --BeginIt; - ArrayRef::iterator EndIt = + ArrayRef::iterator EndIt = llvm::upper_bound(DInfo.Decls, EndLoc, DIDComp); if (EndIt != DInfo.Decls.end()) ++EndIt; - for (ArrayRef::iterator - DIt = BeginIt; DIt != EndIt; ++DIt) + for (ArrayRef::iterator DIt = BeginIt; DIt != EndIt; ++DIt) Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt))); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index bb82173dfe0b..9707eed701e9 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -279,7 +279,7 @@ namespace clang { IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); } - auto *Result = new (C) serialization::DeclID[1 + IDs.size()]; + auto *Result = new (C) DeclID[1 + IDs.size()]; *Result = IDs.size(); std::copy(DeclIDIterator(IDs.begin()), DeclIDIterator(IDs.end()), @@ -4215,7 +4215,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { // The declaration may have been modified by files later in the chain. // If this is the case, read the record containing the updates from each file // and pass it to ASTDeclReader to make the modifications. - serialization::GlobalDeclID ID = Record.ID; + GlobalDeclID ID = Record.ID; Decl *D = Record.D; ProcessingUpdatesRAIIObj ProcessingUpdates(*this); DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID); @@ -4357,7 +4357,7 @@ namespace { llvm::SmallPtrSetImpl &Deserialized; ObjCCategoryDecl *Tail = nullptr; llvm::DenseMap NameCategoryMap; - serialization::GlobalDeclID InterfaceID; + GlobalDeclID InterfaceID; unsigned PreviousGeneration; void add(ObjCCategoryDecl *Cat) { @@ -4399,11 +4399,10 @@ namespace { } public: - ObjCCategoriesVisitor(ASTReader &Reader, - ObjCInterfaceDecl *Interface, - llvm::SmallPtrSetImpl &Deserialized, - serialization::GlobalDeclID InterfaceID, - unsigned PreviousGeneration) + ObjCCategoriesVisitor( + ASTReader &Reader, ObjCInterfaceDecl *Interface, + llvm::SmallPtrSetImpl &Deserialized, + GlobalDeclID InterfaceID, unsigned PreviousGeneration) : Reader(Reader), Interface(Interface), Deserialized(Deserialized), InterfaceID(InterfaceID), PreviousGeneration(PreviousGeneration) { // Populate the name -> category map with the set of known categories. @@ -4457,8 +4456,7 @@ namespace { } // namespace -void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID, - ObjCInterfaceDecl *D, +void ASTReader::loadObjCCategories(GlobalDeclID ID, ObjCInterfaceDecl *D, unsigned PreviousGeneration) { ObjCCategoriesVisitor Visitor(*this, D, CategoriesDeserialized, ID, PreviousGeneration); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 30195868ca99..842ea58656ad 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5100,7 +5100,7 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) { Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); // Write the record containing decls to be checked for deferred diags. - SmallVector DeclsToCheckForDeferredDiags; + SmallVector DeclsToCheckForDeferredDiags; for (auto *D : SemaRef.DeclsToCheckForDeferredDiags) if (wasDeclEmitted(D)) DeclsToCheckForDeferredDiags.push_back(getDeclID(D)); @@ -6079,7 +6079,7 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { if (!Info) Info = std::make_unique(); - std::pair LocDecl(Offset, ID); + std::pair LocDecl(Offset, ID); LocDeclIDsTy &Decls = Info->DeclIDs; Decls.push_back(LocDecl); } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index c6db107e0ca4..fe867192b717 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -2786,9 +2786,9 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { "serializing"); // Determine the ID for this declaration. - serialization::DeclID ID; + DeclID ID; assert(!D->isFromASTFile() && "should not be emitting imported decl"); - serialization::DeclID &IDR = DeclIDs[D]; + DeclID &IDR = DeclIDs[D]; if (IDR == 0) IDR = NextDeclID++; -- GitLab From 42070a5c092ed420bf92ebf38229c594885e94c7 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Thu, 25 Apr 2024 11:43:13 +0800 Subject: [PATCH 055/733] [NFC] [Serialization] Avoid using DeclID directly as much as possible This patch tries to remove all the direct use of DeclID except the real low level reading and writing. All the use of DeclID is converted to the use of LocalDeclID or GlobalDeclID. This is helpful to increase the readability and type safety. --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/AST/Decl.h | 46 ++-- clang/include/clang/AST/DeclBase.h | 8 +- clang/include/clang/AST/DeclCXX.h | 59 ++--- clang/include/clang/AST/DeclFriend.h | 2 +- clang/include/clang/AST/DeclID.h | 140 ++++++++---- clang/include/clang/AST/DeclObjC.h | 30 ++- clang/include/clang/AST/DeclOpenMP.h | 19 +- clang/include/clang/AST/DeclTemplate.h | 50 ++--- clang/include/clang/AST/ExternalASTSource.h | 6 +- clang/include/clang/Frontend/ASTUnit.h | 2 +- .../clang/Frontend/MultiplexConsumer.h | 2 +- .../clang/Sema/MultiplexExternalSemaSource.h | 2 +- .../include/clang/Serialization/ASTBitCodes.h | 27 +-- .../ASTDeserializationListener.h | 2 +- clang/include/clang/Serialization/ASTReader.h | 8 +- clang/include/clang/Serialization/ASTWriter.h | 28 +-- .../include/clang/Serialization/ModuleFile.h | 6 +- clang/lib/AST/ASTContext.cpp | 3 +- clang/lib/AST/Decl.cpp | 47 ++-- clang/lib/AST/DeclBase.cpp | 6 +- clang/lib/AST/DeclCXX.cpp | 67 +++--- clang/lib/AST/DeclFriend.cpp | 2 +- clang/lib/AST/DeclObjC.cpp | 29 +-- clang/lib/AST/DeclOpenMP.cpp | 20 +- clang/lib/AST/DeclTemplate.cpp | 48 ++-- clang/lib/AST/ExternalASTSource.cpp | 2 +- clang/lib/Frontend/ASTUnit.cpp | 8 +- clang/lib/Frontend/FrontendAction.cpp | 6 +- clang/lib/Frontend/MultiplexConsumer.cpp | 3 +- .../lib/Sema/MultiplexExternalSemaSource.cpp | 2 +- clang/lib/Serialization/ASTReader.cpp | 28 +-- clang/lib/Serialization/ASTReaderDecl.cpp | 211 ++++++++---------- clang/lib/Serialization/ASTWriter.cpp | 77 ++++--- clang/lib/Serialization/ASTWriterDecl.cpp | 22 +- 35 files changed, 543 insertions(+), 479 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index ecec9bfcf300..24388ad5dea5 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -455,7 +455,7 @@ class ASTContext : public RefCountedBase { /// initialization of another module). struct PerModuleInitializers { llvm::SmallVector Initializers; - llvm::SmallVector LazyInitializers; + llvm::SmallVector LazyInitializers; void resolve(ASTContext &Ctx); }; @@ -1059,7 +1059,7 @@ public: /// or an ImportDecl nominating another module that has initializers. void addModuleInitializer(Module *M, Decl *Init); - void addLazyModuleInitializers(Module *M, ArrayRef IDs); + void addLazyModuleInitializers(Module *M, ArrayRef IDs); /// Get the initializations to perform when importing a module, if any. ArrayRef getModuleInitializers(Module *M); diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 8b121896d66d..a53c27a99a8c 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -157,7 +157,7 @@ public: SourceLocation CommentLoc, PragmaMSCommentKind CommentKind, StringRef Arg); - static PragmaCommentDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static PragmaCommentDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned ArgSize); PragmaMSCommentKind getCommentKind() const { return CommentKind; } @@ -192,7 +192,7 @@ public: SourceLocation Loc, StringRef Name, StringRef Value); static PragmaDetectMismatchDecl * - CreateDeserialized(ASTContext &C, DeclID ID, unsigned NameValueSize); + CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize); StringRef getName() const { return getTrailingObjects(); } StringRef getValue() const { return getTrailingObjects() + ValueStart; } @@ -518,7 +518,7 @@ public: static LabelDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, SourceLocation GnuLabelL); - static LabelDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static LabelDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); LabelStmt *getStmt() const { return TheStmt; } void setStmt(LabelStmt *T) { TheStmt = T; } @@ -581,7 +581,7 @@ public: IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested); - static NamespaceDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static NamespaceDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -1146,7 +1146,7 @@ public: const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S); - static VarDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static VarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -1728,7 +1728,7 @@ public: static ImplicitParamDecl *Create(ASTContext &C, QualType T, ImplicitParamKind ParamKind); - static ImplicitParamDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ImplicitParamDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType Type, @@ -1782,7 +1782,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg); - static ParmVarDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ParmVarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -2178,7 +2178,7 @@ public: bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause); - static FunctionDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); @@ -3136,7 +3136,7 @@ public: TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle); - static FieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Returns the index of this field within its record, /// as appropriate for passing to ASTRecordLayout::getFieldOffset. @@ -3311,7 +3311,7 @@ public: SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, const llvm::APSInt &V); - static EnumConstantDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static EnumConstantDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); const Expr *getInitExpr() const { return (const Expr*) Init; } Expr *getInitExpr() { return (Expr*) Init; } @@ -3357,7 +3357,7 @@ public: QualType T, llvm::MutableArrayRef CH); - static IndirectFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static IndirectFieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using chain_iterator = ArrayRef::const_iterator; @@ -3542,7 +3542,7 @@ public: static TypedefDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypedefDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TypedefDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3567,7 +3567,7 @@ public: static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypeAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TypeAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3977,7 +3977,7 @@ public: IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed); - static EnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static EnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Overrides to provide correct range when there's an enum-base specifier /// with forward declarations. @@ -4182,7 +4182,7 @@ public: static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr); - static RecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); + static RecordDecl *CreateDeserialized(const ASTContext &C, GlobalDeclID ID); RecordDecl *getPreviousDecl() { return cast_or_null( @@ -4433,7 +4433,7 @@ public: StringLiteral *Str, SourceLocation AsmLoc, SourceLocation RParenLoc); - static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getAsmLoc() const { return getLocation(); } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -4469,7 +4469,7 @@ class TopLevelStmtDecl : public Decl, public DeclContext { public: static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement); - static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; Stmt *getStmt() { return Statement; } @@ -4563,7 +4563,7 @@ protected: public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static BlockDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static BlockDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getCaretLocation() const { return getLocation(); } @@ -4717,7 +4717,7 @@ public: static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); - static CapturedDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static CapturedDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumParams); Stmt *getBody() const override; @@ -4851,7 +4851,7 @@ public: SourceLocation EndLoc); /// Create a new, deserialized module import declaration. - static ImportDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static ImportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumLocations); /// Retrieve the module that was imported by the import declaration. @@ -4892,7 +4892,7 @@ private: public: static ExportDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc); - static ExportDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ExportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getExportLoc() const { return getLocation(); } SourceLocation getRBraceLoc() const { return RBraceLoc; } @@ -4931,7 +4931,7 @@ class EmptyDecl : public Decl { public: static EmptyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static EmptyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static EmptyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Empty; } @@ -4957,7 +4957,7 @@ public: bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); - static HLSLBufferDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(getLocStart(), RBraceLoc); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 474e51c1df6d..e43e812cd945 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -359,7 +359,7 @@ protected: /// \param Ctx The context in which we will allocate memory. /// \param ID The global ID of the deserialized declaration. /// \param Extra The amount of extra space to allocate after the object. - void *operator new(std::size_t Size, const ASTContext &Ctx, DeclID ID, + void *operator new(std::size_t Size, const ASTContext &Ctx, GlobalDeclID ID, std::size_t Extra = 0); /// Allocate memory for a non-deserialized declaration. @@ -777,10 +777,10 @@ public: /// Retrieve the global declaration ID associated with this /// declaration, which specifies where this Decl was loaded from. - DeclID getGlobalID() const { + GlobalDeclID getGlobalID() const { if (isFromASTFile()) - return *((const DeclID *)this - 1); - return 0; + return (*((const GlobalDeclID *)this - 1)); + return GlobalDeclID(); } /// Retrieve the global ID of the module that owns this particular diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index a7644d2a19d2..fb52ac804849 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -120,7 +120,7 @@ public: return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); } - static AccessSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static AccessSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -579,7 +579,8 @@ public: TypeSourceInfo *Info, SourceLocation Loc, unsigned DependencyKind, bool IsGeneric, LambdaCaptureDefault CaptureDefault); - static CXXRecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); + static CXXRecordDecl *CreateDeserialized(const ASTContext &C, + GlobalDeclID ID); bool isDynamicClass() const { return data().Polymorphic || data().NumVBases != 0; @@ -1980,7 +1981,8 @@ public: CXXConstructorDecl *Ctor = nullptr, DeductionCandidate Kind = DeductionCandidate::Normal); - static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; } const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; } @@ -2035,7 +2037,8 @@ public: static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc); - static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2078,7 +2081,7 @@ public: ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static CXXMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); bool isStatic() const; bool isInstance() const { return !isStatic(); } @@ -2579,7 +2582,7 @@ public: friend class ASTDeclWriter; friend TrailingObjects; - static CXXConstructorDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, uint64_t AllocKind); static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, @@ -2822,7 +2825,7 @@ public: bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause = nullptr); - static CXXDestructorDecl *CreateDeserialized(ASTContext & C, DeclID ID); + static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg); @@ -2881,7 +2884,7 @@ public: bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXConversionDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static CXXConversionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ExplicitSpecifier getExplicitSpecifier() { return getCanonicalDecl()->ExplicitSpec; @@ -2948,7 +2951,7 @@ public: SourceLocation ExternLoc, SourceLocation LangLoc, LinkageSpecLanguageIDs Lang, bool HasBraces); - static LinkageSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static LinkageSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the language specified by this linkage specification. LinkageSpecLanguageIDs getLanguage() const { @@ -3096,7 +3099,7 @@ public: SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor); - static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(UsingLoc, getLocation()); @@ -3157,7 +3160,7 @@ public: SourceLocation IdentLoc, NamedDecl *Namespace); - static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3254,7 +3257,7 @@ public: LifetimeExtendedTemporaryDecl(Temp, EDec, Mangling); } static LifetimeExtendedTemporaryDecl *CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) LifetimeExtendedTemporaryDecl(EmptyShell{}); } @@ -3357,7 +3360,7 @@ public: UsingShadowDecl(UsingShadow, C, DC, Loc, Name, Introducer, Target); } - static UsingShadowDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingShadowDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3566,7 +3569,7 @@ public: const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword); - static UsingDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3645,7 +3648,7 @@ public: UsingDecl *Using, NamedDecl *Target, bool IsVirtual); static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); /// Override the UsingShadowDecl's getIntroducer, returning the UsingDecl that /// introduced this. @@ -3757,7 +3760,7 @@ public: SourceLocation UsingL, SourceLocation EnumL, SourceLocation NameL, TypeSourceInfo *EnumType); - static UsingEnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingEnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3830,7 +3833,7 @@ public: NamedDecl *InstantiatedFrom, ArrayRef UsingDecls); - static UsingPackDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static UsingPackDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions); SourceRange getSourceRange() const override LLVM_READONLY { @@ -3923,8 +3926,8 @@ public: NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc); - static UnresolvedUsingValueDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + static UnresolvedUsingValueDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -4014,8 +4017,8 @@ public: SourceLocation TargetNameLoc, DeclarationName TargetName, SourceLocation EllipsisLoc); - static UnresolvedUsingTypenameDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + static UnresolvedUsingTypenameDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); /// Retrieves the canonical declaration of this declaration. UnresolvedUsingTypenameDecl *getCanonicalDecl() override { @@ -4045,7 +4048,7 @@ public: SourceLocation Loc, DeclarationName Name); static UnresolvedUsingIfExistsDecl *CreateDeserialized(ASTContext &Ctx, - DeclID ID); + GlobalDeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingIfExists; } @@ -4073,7 +4076,7 @@ public: SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *Message, SourceLocation RParenLoc, bool Failed); - static StaticAssertDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static StaticAssertDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); } const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); } @@ -4120,7 +4123,7 @@ public: static BindingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id); - static BindingDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static BindingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Get the expression to which this declaration is bound. This may be null /// in two different cases: while parsing the initializer for the @@ -4189,7 +4192,7 @@ public: QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef Bindings); - static DecompositionDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static DecompositionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumBindings); ArrayRef bindings() const { @@ -4246,7 +4249,7 @@ public: SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL, IdentifierInfo *Getter, IdentifierInfo *Setter); - static MSPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static MSPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); static bool classof(const Decl *D) { return D->getKind() == MSProperty; } @@ -4300,7 +4303,7 @@ private: MSGuidDecl(DeclContext *DC, QualType T, Parts P); static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P); - static MSGuidDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static MSGuidDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); // Only ASTContext::getMSGuidDecl and deserialization create these. friend class ASTContext; @@ -4353,7 +4356,7 @@ class UnnamedGlobalConstantDecl : public ValueDecl, static UnnamedGlobalConstantDecl *Create(const ASTContext &C, QualType T, const APValue &APVal); static UnnamedGlobalConstantDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); // Only ASTContext::getUnnamedGlobalConstantDecl and deserialization create // these. diff --git a/clang/include/clang/AST/DeclFriend.h b/clang/include/clang/AST/DeclFriend.h index b56627a5337d..9789282f351a 100644 --- a/clang/include/clang/AST/DeclFriend.h +++ b/clang/include/clang/AST/DeclFriend.h @@ -112,7 +112,7 @@ public: Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, ArrayRef FriendTypeTPLists = std::nullopt); - static FriendDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static FriendDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned FriendTypeNumTPLists); /// If this friend declaration names an (untemplated but possibly diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h index e2c6dd65e86b..614ba06b6386 100644 --- a/clang/include/clang/AST/DeclID.h +++ b/clang/include/clang/AST/DeclID.h @@ -16,6 +16,7 @@ #ifndef LLVM_CLANG_AST_DECLID_H #define LLVM_CLANG_AST_DECLID_H +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/iterator.h" namespace clang { @@ -88,90 +89,139 @@ enum PredefinedDeclIDs { /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. const unsigned int NUM_PREDEF_DECL_IDS = 18; -/// An ID number that refers to a declaration in an AST file. -/// -/// The ID numbers of declarations are consecutive (in order of -/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. -/// At the start of a chain of precompiled headers, declaration ID 1 is -/// used for the translation unit declaration. -using DeclID = uint32_t; +/// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means +/// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the +/// LocalDeclID to the ModuleFile been writting is equal to the GlobalDeclID. +/// Outside the serializer, all the DeclID been used should be GlobalDeclID. +/// We can translate a LocalDeclID to the GlobalDeclID by +/// `ASTReader::getGlobalDeclID()`. -class LocalDeclID { +class DeclIDBase { public: - explicit LocalDeclID(DeclID ID) : ID(ID) {} + /// An ID number that refers to a declaration in an AST file. + /// + /// The ID numbers of declarations are consecutive (in order of + /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. + /// At the start of a chain of precompiled headers, declaration ID 1 is + /// used for the translation unit declaration. + /// + /// DeclID should only be used directly in serialization. All other users + /// should use LocalDeclID or GlobalDeclID. + using DeclID = uint32_t; + +protected: + DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {} + explicit DeclIDBase(DeclID ID) : ID(ID) {} +public: DeclID get() const { return ID; } -private: - DeclID ID; -}; + explicit operator DeclID() const { return ID; } -/// Wrapper class for DeclID. This is helpful to not mix the use of LocalDeclID -/// and GlobalDeclID to improve the type safety. -class GlobalDeclID { -public: - GlobalDeclID() : ID(PREDEF_DECL_NULL_ID) {} - explicit GlobalDeclID(DeclID ID) : ID(ID) {} + explicit operator PredefinedDeclIDs() const { return (PredefinedDeclIDs)ID; } - DeclID get() const { return ID; } + bool isValid() const { return ID != PREDEF_DECL_NULL_ID; } - explicit operator DeclID() const { return ID; } + bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; } - friend bool operator==(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID == RHS.ID; } - friend bool operator!=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID != RHS.ID; } - // We may sort the global decl ID. - friend bool operator<(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + // We may sort the decl ID. + friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID < RHS.ID; } - friend bool operator>(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator>(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID > RHS.ID; } - friend bool operator<=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator<=(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID <= RHS.ID; } - friend bool operator>=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator>=(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID >= RHS.ID; } -private: +protected: DeclID ID; }; -/// A helper iterator adaptor to convert the iterators to `SmallVector` -/// to the iterators to `SmallVector`. -class GlobalDeclIDIterator - : public llvm::iterator_adaptor_base { +class LocalDeclID : public DeclIDBase { + using Base = DeclIDBase; + public: - GlobalDeclIDIterator() : iterator_adaptor_base(nullptr) {} + LocalDeclID() : Base() {} + LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {} + explicit LocalDeclID(DeclID ID) : Base(ID) {} + + LocalDeclID &operator++() { + ++ID; + return *this; + } + + LocalDeclID operator++(int) { + LocalDeclID Ret = *this; + ++(*this); + return Ret; + } +}; - GlobalDeclIDIterator(const DeclID *ID) : iterator_adaptor_base(ID) {} +class GlobalDeclID : public DeclIDBase { + using Base = DeclIDBase; - value_type operator*() const { return GlobalDeclID(*I); } +public: + GlobalDeclID() : Base() {} + explicit GlobalDeclID(DeclID ID) : Base(ID) {} - bool operator==(const GlobalDeclIDIterator &RHS) const { return I == RHS.I; } + // For DeclIDIterator to be able to convert a GlobalDeclID + // to a LocalDeclID. + explicit operator LocalDeclID() const { return LocalDeclID(this->ID); } }; /// A helper iterator adaptor to convert the iterators to -/// `SmallVector` to the iterators to `SmallVector`. +/// `SmallVector` to the iterators to `SmallVector`. +template class DeclIDIterator - : public llvm::iterator_adaptor_base { + : public llvm::iterator_adaptor_base, + const FromTy *, + std::forward_iterator_tag, ToTy> { public: - DeclIDIterator() : iterator_adaptor_base(nullptr) {} + DeclIDIterator() : DeclIDIterator::iterator_adaptor_base(nullptr) {} - DeclIDIterator(const GlobalDeclID *ID) : iterator_adaptor_base(ID) {} + DeclIDIterator(const FromTy *ID) + : DeclIDIterator::iterator_adaptor_base(ID) {} - value_type operator*() const { return DeclID(*I); } + ToTy operator*() const { return ToTy(*this->I); } - bool operator==(const DeclIDIterator &RHS) const { return I == RHS.I; } + bool operator==(const DeclIDIterator &RHS) const { return this->I == RHS.I; } }; } // namespace clang +namespace llvm { +template <> struct DenseMapInfo { + using GlobalDeclID = clang::GlobalDeclID; + using DeclID = GlobalDeclID::DeclID; + + static GlobalDeclID getEmptyKey() { + return GlobalDeclID(DenseMapInfo::getEmptyKey()); + } + + static GlobalDeclID getTombstoneKey() { + return GlobalDeclID(DenseMapInfo::getTombstoneKey()); + } + + static unsigned getHashValue(const GlobalDeclID &Key) { + return DenseMapInfo::getHashValue(Key.get()); + } + + static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) { + return L == R; + } +}; + +} // namespace llvm + #endif diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 7780afa6f1cf..d2cc61ca19f8 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -236,7 +236,7 @@ public: ObjCImplementationControl impControl = ObjCImplementationControl::None, bool HasRelatedResultType = false); - static ObjCMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ObjCMethodDecl *getCanonicalDecl() override; const ObjCMethodDecl *getCanonicalDecl() const { @@ -614,7 +614,8 @@ public: IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo); - static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, DeclID ID); + static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -789,7 +790,7 @@ public: TypeSourceInfo *TSI, PropertyControl propControl = None); - static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } @@ -1279,7 +1280,8 @@ public: ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc = SourceLocation(), bool isInternal = false); - static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, DeclID ID); + static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, + GlobalDeclID ID); /// Retrieve the type parameters of this class. /// @@ -1969,7 +1971,7 @@ public: TypeSourceInfo *TInfo, AccessControl ac, Expr *BW = nullptr, bool synthesized = false); - static ObjCIvarDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the class interface that this ivar is logically contained /// in; this is either the interface where the ivar was declared, or the @@ -2039,7 +2041,8 @@ public: SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW); - static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2142,7 +2145,7 @@ public: SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl); - static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); const ObjCProtocolList &getReferencedProtocols() const { assert(hasDefinition() && "No definition available!"); @@ -2361,7 +2364,7 @@ public: ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc = SourceLocation(), SourceLocation IvarRBraceLoc = SourceLocation()); - static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -2558,7 +2561,8 @@ public: Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc); - static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); ObjCCategoryDecl *getCategoryDecl() const; @@ -2640,7 +2644,8 @@ public: SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()); - static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); /// init_iterator - Iterates through the ivar initializer list. using init_iterator = CXXCtorInitializer **; @@ -2780,7 +2785,7 @@ public: ObjCInterfaceDecl* aliasedClass); static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } @@ -2851,7 +2856,8 @@ public: ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc); - static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h index c7ede7f2157f..cad7a619a635 100644 --- a/clang/include/clang/AST/DeclOpenMP.h +++ b/clang/include/clang/AST/DeclOpenMP.h @@ -59,9 +59,9 @@ protected: } template - static T *createEmptyDirective(const ASTContext &C, unsigned ID, + static T *createEmptyDirective(const ASTContext &C, GlobalDeclID ID, unsigned NumClauses, unsigned NumChildren, - Params &&... P) { + Params &&...P) { auto *Inst = new (C, ID, size(NumClauses, NumChildren)) T(nullptr, std::forward(P)...); Inst->Data = OMPChildren::CreateEmpty( @@ -133,7 +133,7 @@ public: SourceLocation L, ArrayRef VL); static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, - DeclID ID, unsigned N); + GlobalDeclID ID, unsigned N); typedef MutableArrayRef::iterator varlist_iterator; typedef ArrayRef::iterator varlist_const_iterator; @@ -214,7 +214,7 @@ public: QualType T, OMPDeclareReductionDecl *PrevDeclInScope); /// Create deserialized declare reduction node. static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); /// Get combiner expression of the declare reduction construct. Expr *getCombiner() { return Combiner; } @@ -318,8 +318,8 @@ public: ArrayRef Clauses, OMPDeclareMapperDecl *PrevDeclInScope); /// Creates deserialized declare mapper node. - static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, DeclID ID, - unsigned N); + static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; using clauselist_const_iterator = ArrayRef::iterator; @@ -397,7 +397,8 @@ public: IdentifierInfo *Id, QualType T, SourceLocation StartLoc); - static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -427,7 +428,7 @@ public: static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef CL); /// Create deserialized requires node. - static OMPRequiresDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static OMPRequiresDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; @@ -495,7 +496,7 @@ public: static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef VL, ArrayRef CL); - static OMPAllocateDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static OMPAllocateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NVars, unsigned NClauses); typedef MutableArrayRef::iterator varlist_iterator; diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 0c95459a6ab1..3ee03eebdb8c 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -797,7 +797,7 @@ protected: /// /// The first value in the array is the number of specializations/partial /// specializations that follow. - DeclID *LazySpecializations = nullptr; + GlobalDeclID *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -1087,7 +1087,8 @@ public: NamedDecl *Decl); /// Create an empty function template node. - static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1204,9 +1205,9 @@ public: bool Typename, bool ParameterPack, bool HasTypeConstraint = false, std::optional NumExpanded = std::nullopt); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - DeclID ID); + GlobalDeclID ID); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - DeclID ID, + GlobalDeclID ID, bool HasTypeConstraint); /// Whether this template type parameter was declared with @@ -1413,11 +1414,10 @@ public: QualType T, TypeSourceInfo *TInfo, ArrayRef ExpandedTypes, ArrayRef ExpandedTInfos); + static NonTypeTemplateParmDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID, - bool HasTypeConstraint); - static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID, + GlobalDeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint); @@ -1632,10 +1632,9 @@ public: ArrayRef Expansions); static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID); - static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID, - unsigned NumExpansions); + GlobalDeclID ID); + static TemplateTemplateParmDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions); using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; @@ -1857,8 +1856,8 @@ public: ClassTemplateDecl *SpecializedTemplate, ArrayRef Args, ClassTemplateSpecializationDecl *PrevDecl); - static ClassTemplateSpecializationDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2110,7 +2109,7 @@ public: ClassTemplatePartialSpecializationDecl *PrevDecl); static ClassTemplatePartialSpecializationDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + CreateDeserialized(ASTContext &C, GlobalDeclID ID); ClassTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -2306,7 +2305,7 @@ public: NamedDecl *Decl); /// Create an empty class template node. - static ClassTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ClassTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -2472,7 +2471,7 @@ public: MutableArrayRef Params, FriendUnion Friend, SourceLocation FriendLoc); - static FriendTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// If this friend declaration names a templated type (or /// a dependent member type of a templated type), return that @@ -2573,7 +2572,8 @@ public: NamedDecl *Decl); /// Create an empty alias template node. - static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2670,7 +2670,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args); static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2900,8 +2900,8 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args, const TemplateArgumentListInfo &ArgInfos); - static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + static VarTemplatePartialSpecializationDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID); VarTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -3078,7 +3078,7 @@ public: VarDecl *Decl); /// Create an empty variable template node. - static VarTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static VarTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -3183,7 +3183,7 @@ public: SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr); - static ConceptDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ConceptDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); Expr *getConstraintExpr() const { return ConstraintExpr; @@ -3232,7 +3232,7 @@ public: Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef ConvertedArgs); static ImplicitConceptSpecializationDecl * - CreateDeserialized(const ASTContext &C, DeclID ID, + CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs); ArrayRef getTemplateArguments() const { @@ -3275,7 +3275,7 @@ private: static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T, const APValue &V); static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); /// Only ASTContext::getTemplateParamObjectDecl and deserialization /// create these. diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index d0ee8ce6365a..385c32edbae0 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -99,7 +99,7 @@ public: /// passes back decl sets as VisibleDeclaration objects. /// /// The default implementation of this method is a no-op. - virtual Decl *GetExternalDecl(DeclID ID); + virtual Decl *GetExternalDecl(GlobalDeclID ID); /// Resolve a selector ID into a selector. /// @@ -375,7 +375,7 @@ public: if (isOffset()) { assert(Source && "Cannot deserialize a lazy pointer without an AST source"); - Ptr = reinterpret_cast((Source->*Get)(Ptr >> 1)); + Ptr = reinterpret_cast((Source->*Get)(OffsT(Ptr >> 1))); } return reinterpret_cast(Ptr); } @@ -579,7 +579,7 @@ using LazyDeclStmtPtr = /// A lazy pointer to a declaration. using LazyDeclPtr = - LazyOffsetPtr; + LazyOffsetPtr; /// A lazy pointer to a set of CXXCtorInitializers. using LazyCXXCtorInitializersPtr = diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 163e87cd3df3..080844893c13 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -241,7 +241,7 @@ private: /// A list of the serialization ID numbers for each of the top-level /// declarations parsed within the precompiled preamble. - std::vector TopLevelDeclsInPreamble; + std::vector TopLevelDeclsInPreamble; /// Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults : 1; diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h b/clang/include/clang/Frontend/MultiplexConsumer.h index 6a82c0dd8cec..f29c8e92fded 100644 --- a/clang/include/clang/Frontend/MultiplexConsumer.h +++ b/clang/include/clang/Frontend/MultiplexConsumer.h @@ -35,7 +35,7 @@ public: void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; void MacroRead(serialization::MacroID ID, MacroInfo *MI) override; void TypeRead(serialization::TypeIdx Idx, QualType T) override; - void DeclRead(DeclID ID, const Decl *D) override; + void DeclRead(GlobalDeclID ID, const Decl *D) override; void SelectorRead(serialization::SelectorID iD, Selector Sel) override; void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD) override; diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index da3204863a41..238fb398b7d1 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -65,7 +65,7 @@ public: /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. - Decl *GetExternalDecl(DeclID ID) override; + Decl *GetExternalDecl(GlobalDeclID ID) override; /// Complete the redeclaration chain if it's been extended since the /// previous generation of the AST source. diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 42e09a2bf634..186c3b722ced 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -60,6 +60,10 @@ const unsigned VERSION_MINOR = 1; /// and start at 1. 0 is reserved for NULL. using IdentifierID = uint32_t; +/// An ID number that refers to a declaration in an AST file. See the comments +/// in DeclIDBase for details. +using DeclID = DeclIDBase::DeclID; + /// An ID number that refers to a type in an AST file. /// /// The ID of a type is partitioned into two parts: the lower @@ -1979,7 +1983,7 @@ enum CleanupObjectKind { COK_Block, COK_CompoundLiteral }; /// Describes the categories of an Objective-C class. struct ObjCCategoriesInfo { // The ID of the definition - DeclID DefinitionID; + LocalDeclID DefinitionID; // Offset into the array of category lists. unsigned Offset; @@ -2078,27 +2082,6 @@ template <> struct DenseMapInfo { } }; -template <> struct DenseMapInfo { - using DeclID = clang::DeclID; - using GlobalDeclID = clang::GlobalDeclID; - - static GlobalDeclID getEmptyKey() { - return GlobalDeclID(DenseMapInfo::getEmptyKey()); - } - - static GlobalDeclID getTombstoneKey() { - return GlobalDeclID(DenseMapInfo::getTombstoneKey()); - } - - static unsigned getHashValue(const GlobalDeclID &Key) { - return DenseMapInfo::getHashValue(Key.get()); - } - - static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) { - return L == R; - } -}; - } // namespace llvm #endif // LLVM_CLANG_SERIALIZATION_ASTBITCODES_H diff --git a/clang/include/clang/Serialization/ASTDeserializationListener.h b/clang/include/clang/Serialization/ASTDeserializationListener.h index bb039558f7f7..3ab7f1a91843 100644 --- a/clang/include/clang/Serialization/ASTDeserializationListener.h +++ b/clang/include/clang/Serialization/ASTDeserializationListener.h @@ -44,7 +44,7 @@ public: /// unqualified. virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { } /// A decl was deserialized from the AST file. - virtual void DeclRead(DeclID ID, const Decl *D) {} + virtual void DeclRead(GlobalDeclID ID, const Decl *D) {} /// A selector was read from the AST file. virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {} /// A macro definition was read from the AST file. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 65e2bcb990c3..64f1ebc117b3 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -603,7 +603,8 @@ private: /// Decl::Kind, DeclID pairs. using unalighed_decl_id_t = llvm::support::detail::packed_endian_specific_integral< - DeclID, llvm::endianness::native, llvm::support::unaligned>; + serialization::DeclID, llvm::endianness::native, + llvm::support::unaligned>; using LexicalContents = ArrayRef; /// Map from a DeclContext to its lexical contents. @@ -1918,7 +1919,7 @@ public: /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. Decl *GetDecl(GlobalDeclID ID); - Decl *GetExternalDecl(DeclID ID) override; + Decl *GetExternalDecl(GlobalDeclID ID) override; /// Resolve a declaration ID into a declaration. Return 0 if it's not /// been loaded yet. @@ -1941,7 +1942,8 @@ public: /// /// \returns the global ID of the given declaration as known in the given /// module file. - DeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M, GlobalDeclID GlobalID); + LocalDeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + GlobalDeclID GlobalID); /// Reads a declaration ID from the given position in a record in the /// given module. diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index d01b31549248..6c45b7348b85 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -212,10 +212,10 @@ private: llvm::SmallVector DelayedNamespace; /// The first ID number we can use for our own declarations. - DeclID FirstDeclID = clang::NUM_PREDEF_DECL_IDS; + LocalDeclID FirstDeclID = LocalDeclID(clang::NUM_PREDEF_DECL_IDS); /// The decl ID that will be assigned to the next new decl. - DeclID NextDeclID = FirstDeclID; + LocalDeclID NextDeclID = FirstDeclID; /// Map that provides the ID numbers of each declaration within /// the output stream, as well as those deserialized from a chained PCH. @@ -223,7 +223,7 @@ private: /// The ID numbers of declarations are consecutive (in order of /// discovery) and start at 2. 1 is reserved for the translation /// unit, while 0 is reserved for NULL. - llvm::DenseMap DeclIDs; + llvm::DenseMap DeclIDs; /// Offset of each declaration in the bitstream, indexed by /// the declaration's ID. @@ -233,8 +233,8 @@ private: /// are relative to this value. uint64_t DeclTypesBlockStartOffset = 0; - /// Sorted (by file offset) vector of pairs of file offset/DeclID. - using LocDeclIDsTy = SmallVector, 64>; + /// Sorted (by file offset) vector of pairs of file offset/LocalDeclID. + using LocDeclIDsTy = SmallVector, 64>; struct DeclIDInFileInfo { LocDeclIDsTy DeclIDs; @@ -249,7 +249,7 @@ private: /// that it contains. FileDeclIDsTy FileDeclIDs; - void associateDeclWithFile(const Decl *D, DeclID); + void associateDeclWithFile(const Decl *D, LocalDeclID); /// The first ID number we can use for our own types. serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS; @@ -420,8 +420,8 @@ private: /// headers. The declarations themselves are stored as declaration /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS /// record. - SmallVector EagerlyDeserializedDecls; - SmallVector ModularCodegenDecls; + RecordData EagerlyDeserializedDecls; + RecordData ModularCodegenDecls; /// DeclContexts that have received extensions since their serialized /// form. @@ -707,7 +707,8 @@ public: if (D->isFromASTFile()) return false; auto I = DeclIDs.find(D); - return (I == DeclIDs.end() || I->second >= clang::NUM_PREDEF_DECL_IDS); + return (I == DeclIDs.end() || + I->second.get() >= clang::NUM_PREDEF_DECL_IDS); }; /// Emit a reference to a declaration. @@ -715,12 +716,13 @@ public: // Emit a reference to a declaration if the declaration was emitted. void AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record); - /// Force a declaration to be emitted and get its ID. - DeclID GetDeclRef(const Decl *D); + /// Force a declaration to be emitted and get its local ID to the module file + /// been writing. + LocalDeclID GetDeclRef(const Decl *D); - /// Determine the declaration ID of an already-emitted + /// Determine the local declaration ID of an already-emitted /// declaration. - DeclID getDeclID(const Decl *D); + LocalDeclID getDeclID(const Decl *D); /// Whether or not the declaration got emitted. If not, it wouldn't be /// emitted. diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 1f7222655876..25f644e76edb 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -459,10 +459,10 @@ public: const DeclOffset *DeclOffsets = nullptr; /// Base declaration ID for declarations local to this module. - DeclID BaseDeclID = 0; + serialization::DeclID BaseDeclID = 0; /// Remapping table for declaration IDs in this module. - ContinuousRangeMap DeclRemap; + ContinuousRangeMap DeclRemap; /// Mapping from the module files that this module file depends on /// to the base declaration ID for that module as it is understood within this @@ -471,7 +471,7 @@ public: /// This is effectively a reverse global-to-local mapping for declaration /// IDs, so that we can interpret a true global ID (for this translation unit) /// as a local ID (for this module file). - llvm::DenseMap GlobalToLocalDeclIDs; + llvm::DenseMap GlobalToLocalDeclIDs; /// Array of file-level DeclIDs sorted by file. const LocalDeclID *FileSortedDecls = nullptr; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a7386f755ca0..475b47afa639 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1083,7 +1083,8 @@ void ASTContext::addModuleInitializer(Module *M, Decl *D) { Inits->Initializers.push_back(D); } -void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef IDs) { +void ASTContext::addLazyModuleInitializers(Module *M, + ArrayRef IDs) { auto *&Inits = ModuleInitializers[M]; if (!Inits) Inits = new (*this) PerModuleInitializers; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index f452902110c7..e7e95c16b697 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2151,7 +2151,7 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartL, return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S); } -VarDecl *VarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +VarDecl *VarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None); @@ -2929,7 +2929,7 @@ QualType ParmVarDecl::getOriginalType() const { return T; } -ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None, nullptr); @@ -4553,7 +4553,7 @@ FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC, BW, Mutable, InitStyle); } -FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, nullptr, false, ICIS_NoInit); @@ -4863,7 +4863,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, return Enum; } -EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { EnumDecl *Enum = new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr, false, false, false); @@ -5025,7 +5025,8 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, return R; } -RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, DeclID ID) { +RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, + GlobalDeclID ID) { RecordDecl *R = new (C, ID) RecordDecl(Record, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -5297,7 +5298,7 @@ PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, } PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C, - DeclID ID, + GlobalDeclID ID, unsigned ArgSize) { return new (C, ID, additionalSizeToAlloc(ArgSize + 1)) PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown); @@ -5322,7 +5323,7 @@ PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC, } PragmaDetectMismatchDecl * -PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, DeclID ID, +PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize) { return new (C, ID, additionalSizeToAlloc(NameValueSize + 1)) PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0); @@ -5349,7 +5350,7 @@ LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL); } -LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation()); } @@ -5390,7 +5391,7 @@ ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, QualType Type, } ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other); } @@ -5408,7 +5409,7 @@ FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, return New; } -FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) FunctionDecl( Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -5418,7 +5419,7 @@ BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) BlockDecl(DC, L); } -BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) BlockDecl(nullptr, SourceLocation()); } @@ -5432,7 +5433,7 @@ CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC, CapturedDecl(DC, NumParams); } -CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, DeclID ID, +CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumParams) { return new (C, ID, additionalSizeToAlloc(NumParams)) CapturedDecl(nullptr, NumParams); @@ -5459,7 +5460,7 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, } EnumConstantDecl *EnumConstantDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) EnumConstantDecl(C, nullptr, SourceLocation(), nullptr, QualType(), nullptr, llvm::APSInt()); } @@ -5486,7 +5487,7 @@ IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) IndirectFieldDecl(C, nullptr, SourceLocation(), DeclarationName(), QualType(), std::nullopt); @@ -5547,7 +5548,7 @@ bool TypedefNameDecl::isTransparentTagSlow() const { return isTransparent; } -TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5560,7 +5561,8 @@ TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo); } -TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5591,7 +5593,7 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, } FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -5609,7 +5611,7 @@ TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) { } TopLevelStmtDecl *TopLevelStmtDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) TopLevelStmtDecl(/*DC=*/nullptr, SourceLocation(), /*S=*/nullptr); } @@ -5630,7 +5632,7 @@ EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) EmptyDecl(DC, L); } -EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) EmptyDecl(nullptr, SourceLocation()); } @@ -5663,7 +5665,8 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C, return Result; } -HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr, SourceLocation(), SourceLocation()); } @@ -5719,7 +5722,7 @@ ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC, return Import; } -ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, DeclID ID, +ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumLocations) { return new (C, ID, additionalSizeToAlloc(NumLocations)) ImportDecl(EmptyShell()); @@ -5752,6 +5755,6 @@ ExportDecl *ExportDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) ExportDecl(DC, ExportLoc); } -ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ExportDecl(nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index a2d88cf7a6a1..c33babf8d1df 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -70,8 +70,8 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const { #define ABSTRACT_DECL(DECL) #include "clang/AST/DeclNodes.inc" -void *Decl::operator new(std::size_t Size, const ASTContext &Context, DeclID ID, - std::size_t Extra) { +void *Decl::operator new(std::size_t Size, const ASTContext &Context, + GlobalDeclID ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. static_assert(sizeof(unsigned) * 2 >= alignof(Decl), @@ -85,7 +85,7 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, DeclID ID, PrefixPtr[0] = 0; // Store the global declaration ID in the second 4 bytes. - PrefixPtr[1] = ID; + PrefixPtr[1] = ID.get(); return Result; } diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index c525c3368ce2..75c441293d62 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -57,7 +57,8 @@ using namespace clang; void AccessSpecDecl::anchor() {} -AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) AccessSpecDecl(EmptyShell()); } @@ -68,7 +69,7 @@ void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const { for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I) I.setDecl(cast(Source->GetExternalDecl( - reinterpret_cast(I.getDecl()) >> 2))); + GlobalDeclID(reinterpret_cast(I.getDecl()) >> 2)))); Impl.Decls.setLazy(false); } @@ -161,7 +162,7 @@ CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, } CXXRecordDecl *CXXRecordDecl::CreateDeserialized(const ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { auto *R = new (C, ID) CXXRecordDecl(CXXRecord, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -2162,8 +2163,8 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( TInfo, EndLocation, Ctor, Kind); } -CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +CXXDeductionGuideDecl * +CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) CXXDeductionGuideDecl( C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), QualType(), nullptr, SourceLocation(), nullptr, @@ -2175,8 +2176,8 @@ RequiresExprBodyDecl *RequiresExprBodyDecl::Create( return new (C, DC) RequiresExprBodyDecl(C, DC, StartLoc); } -RequiresExprBodyDecl *RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +RequiresExprBodyDecl * +RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) RequiresExprBodyDecl(C, nullptr, SourceLocation()); } @@ -2281,7 +2282,8 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, isInline, ConstexprKind, EndLocation, TrailingRequiresClause); } -CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) CXXMethodDecl( CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, @@ -2699,7 +2701,7 @@ CXXConstructorDecl::CXXConstructorDecl( void CXXConstructorDecl::anchor() {} CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, - DeclID ID, + GlobalDeclID ID, uint64_t AllocKind) { bool hasTrailingExplicit = static_cast(AllocKind & TAKHasTailExplicit); bool isInheritingConstructor = @@ -2846,7 +2848,7 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const { void CXXDestructorDecl::anchor() {} CXXDestructorDecl *CXXDestructorDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) CXXDestructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -2878,7 +2880,7 @@ void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) { void CXXConversionDecl::anchor() {} CXXConversionDecl *CXXConversionDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) CXXConversionDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified, @@ -2923,7 +2925,8 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces); } -LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(), SourceLocation(), LinkageSpecLanguageIDs::C, false); @@ -2945,7 +2948,7 @@ UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, } UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), @@ -2984,7 +2987,8 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, PrevDecl, Nested); } -NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(), SourceLocation(), nullptr, nullptr, false); } @@ -3046,7 +3050,7 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, } NamespaceAliasDecl *NamespaceAliasDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, NestedNameSpecifierLoc(), @@ -3101,7 +3105,8 @@ UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty) : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()), redeclarable_base(C) {} -UsingShadowDecl *UsingShadowDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UsingShadowDecl *UsingShadowDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell()); } @@ -3124,7 +3129,7 @@ ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC, } ConstructorUsingShadowDecl * -ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell()); } @@ -3172,7 +3177,7 @@ UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL, return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename); } -UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) UsingDecl(nullptr, SourceLocation(), NestedNameSpecifierLoc(), DeclarationNameInfo(), false); @@ -3196,7 +3201,8 @@ UsingEnumDecl *UsingEnumDecl::Create(ASTContext &C, DeclContext *DC, UsingEnumDecl(DC, EnumType->getType()->getAsTagDecl()->getDeclName(), UL, EL, NL, EnumType); } -UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) UsingEnumDecl(nullptr, DeclarationName(), SourceLocation(), SourceLocation(), SourceLocation(), nullptr); @@ -3215,7 +3221,7 @@ UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls); } -UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, DeclID ID, +UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions) { size_t Extra = additionalSizeToAlloc(NumExpansions); auto *Result = @@ -3241,7 +3247,7 @@ UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingValueDecl * -UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(), SourceLocation(), NestedNameSpecifierLoc(), @@ -3271,7 +3277,8 @@ UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingTypenameDecl * -UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) UnresolvedUsingTypenameDecl( nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), nullptr, SourceLocation()); @@ -3284,7 +3291,8 @@ UnresolvedUsingIfExistsDecl::Create(ASTContext &Ctx, DeclContext *DC, } UnresolvedUsingIfExistsDecl * -UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, DeclID ID) { +UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, + GlobalDeclID ID) { return new (Ctx, ID) UnresolvedUsingIfExistsDecl(nullptr, SourceLocation(), DeclarationName()); } @@ -3308,7 +3316,7 @@ StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, } StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), false); } @@ -3330,7 +3338,7 @@ BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) BindingDecl(DC, IdLoc, Id); } -BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); } @@ -3361,7 +3369,7 @@ DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, } DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C, - DeclID ID, + GlobalDeclID ID, unsigned NumBindings) { size_t Extra = additionalSizeToAlloc(NumBindings); auto *Result = new (C, ID, Extra) @@ -3399,7 +3407,8 @@ MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) MSPropertyDecl(DC, L, N, T, TInfo, StartL, Getter, Setter); } -MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(), DeclarationName(), QualType(), nullptr, SourceLocation(), nullptr, nullptr); @@ -3416,7 +3425,7 @@ MSGuidDecl *MSGuidDecl::Create(const ASTContext &C, QualType T, Parts P) { return new (C, DC) MSGuidDecl(DC, T, P); } -MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) MSGuidDecl(nullptr, QualType(), Parts()); } @@ -3526,7 +3535,7 @@ UnnamedGlobalConstantDecl::Create(const ASTContext &C, QualType T, } UnnamedGlobalConstantDecl * -UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) UnnamedGlobalConstantDecl(C, nullptr, QualType(), APValue()); } diff --git a/clang/lib/AST/DeclFriend.cpp b/clang/lib/AST/DeclFriend.cpp index f6d11e550b57..04b9b93699f3 100644 --- a/clang/lib/AST/DeclFriend.cpp +++ b/clang/lib/AST/DeclFriend.cpp @@ -62,7 +62,7 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, return FD; } -FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, DeclID ID, +FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned FriendTypeNumTPLists) { std::size_t Extra = additionalSizeToAlloc(FriendTypeNumTPLists); diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index f98ec6727e48..83062b0e6887 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -862,7 +862,8 @@ ObjCMethodDecl *ObjCMethodDecl::Create( isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); } -ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(), Selector(), QualType(), nullptr, nullptr); } @@ -1486,7 +1487,7 @@ ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc, } ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx, - DeclID ID) { + GlobalDeclID ID) { return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr, ObjCTypeParamVariance::Invariant, SourceLocation(), 0, SourceLocation(), @@ -1551,7 +1552,7 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create( } ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { auto *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), nullptr, false); @@ -1865,7 +1866,7 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, synthesized); } -ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, ObjCIvarDecl::None, nullptr, false); @@ -1914,7 +1915,7 @@ ObjCAtDefsFieldDecl } ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr); @@ -1949,7 +1950,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, } ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { ObjCProtocolDecl *Result = new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(), SourceLocation(), nullptr); @@ -2148,7 +2149,7 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create( } ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(), SourceLocation(), SourceLocation(), nullptr, nullptr, nullptr); @@ -2188,8 +2189,8 @@ ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create( atStartLoc, CategoryNameLoc); } -ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +ObjCCategoryImplDecl * +ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation(), SourceLocation()); @@ -2296,7 +2297,7 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, } ObjCImplementationDecl * -ObjCImplementationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ObjCImplementationDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -2339,7 +2340,7 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, } ObjCCompatibleAliasDecl * -ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(), nullptr, nullptr); } @@ -2360,7 +2361,7 @@ ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr, SourceLocation(), SourceLocation(), QualType(), nullptr, None); @@ -2392,8 +2393,8 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, ivarLoc); } -ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +ObjCPropertyImplDecl * +ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, Dynamic, nullptr, SourceLocation()); diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp index 9f1d2bd41235..81ca48e60942 100644 --- a/clang/lib/AST/DeclOpenMP.cpp +++ b/clang/lib/AST/DeclOpenMP.cpp @@ -35,8 +35,9 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C, return D; } -OMPThreadPrivateDecl * -OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { +OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, + unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, 0, N); } @@ -62,7 +63,8 @@ OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC, return D; } -OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, DeclID ID, +OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned NVars, unsigned NClauses) { return OMPDeclarativeDirective::createEmptyDirective( @@ -88,7 +90,8 @@ OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC, L); } -OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, DeclID ID, +OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 0, SourceLocation()); @@ -116,7 +119,7 @@ OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create( } OMPDeclareReductionDecl * -OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) OMPDeclareReductionDecl( OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(), QualType(), /*PrevDeclInScope=*/nullptr); @@ -146,8 +149,9 @@ OMPDeclareMapperDecl *OMPDeclareMapperDecl::Create( C, DC, Clauses, 1, L, Name, T, VarName, PrevDeclInScope); } -OMPDeclareMapperDecl * -OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { +OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, + unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 1, SourceLocation(), DeclarationName(), QualType(), DeclarationName(), /*PrevDeclInScope=*/nullptr); @@ -177,7 +181,7 @@ OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC, } OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType(), /*TInfo=*/nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index ca998b502bee..d27a30e0c5fc 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -337,9 +337,10 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); if (CommonBasePtr->LazySpecializations) { ASTContext &Context = getASTContext(); - DeclID *Specs = CommonBasePtr->LazySpecializations; + GlobalDeclID *Specs = CommonBasePtr->LazySpecializations; CommonBasePtr->LazySpecializations = nullptr; - for (uint32_t I = 0, N = *Specs++; I != N; ++I) + unsigned SpecSize = (*Specs++).get(); + for (unsigned I = 0; I != SpecSize; ++I) (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); } } @@ -417,8 +418,8 @@ FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, return TD; } -FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +FunctionTemplateDecl * +FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -503,7 +504,7 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC, } ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -652,14 +653,14 @@ TemplateTypeParmDecl *TemplateTypeParmDecl::Create( } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, DeclID ID) { +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) { return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, false, false, std::nullopt); } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, DeclID ID, +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc(HasTypeConstraint ? 1 : 0)) @@ -759,7 +760,7 @@ NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc, @@ -770,7 +771,7 @@ NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint) { auto *NTTP = @@ -836,13 +837,13 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, false, nullptr, false, nullptr); } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions) { auto *TTP = new (C, ID, additionalSizeToAlloc(NumExpansions)) @@ -948,7 +949,8 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, } ClassTemplateSpecializationDecl * -ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { auto *Result = new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); Result->setMayHaveOutOfDateDef(false); @@ -1034,7 +1036,7 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, return TD; } -ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); @@ -1068,7 +1070,7 @@ ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( ImplicitConceptSpecializationDecl * ImplicitConceptSpecializationDecl::CreateDeserialized( - const ASTContext &C, DeclID ID, unsigned NumTemplateArgs) { + const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) { return new (C, ID, additionalSizeToAlloc(NumTemplateArgs)) ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); } @@ -1131,7 +1133,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, ClassTemplatePartialSpecializationDecl * ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); Result->setMayHaveOutOfDateDef(false); return Result; @@ -1158,7 +1160,7 @@ FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, } FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) FriendTemplateDecl(EmptyShell()); } @@ -1177,8 +1179,8 @@ TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, return TD; } -TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +TypeAliasTemplateDecl * +TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1215,7 +1217,8 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, return TD; } -VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1337,7 +1340,8 @@ VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( } VarTemplateSpecializationDecl * -VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) VarTemplateSpecializationDecl(VarTemplateSpecialization, C); } @@ -1429,7 +1433,7 @@ VarTemplatePartialSpecializationDecl::Create( VarTemplatePartialSpecializationDecl * VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) VarTemplatePartialSpecializationDecl(C); } @@ -1543,7 +1547,7 @@ TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C, } TemplateParamObjectDecl * -TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue()); C.addDestruction(&TPOD->Value); return TPOD; diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index 26ded22bf329..e96a47496851 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -68,7 +68,7 @@ bool ExternalASTSource::layoutRecordType( return false; } -Decl *ExternalASTSource::GetExternalDecl(DeclID ID) { return nullptr; } +Decl *ExternalASTSource::GetExternalDecl(GlobalDeclID ID) { return nullptr; } Selector ExternalASTSource::GetExternalSelector(uint32_t ID) { return Selector(); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 361331de145b..2f75313e8a4c 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1067,7 +1067,7 @@ public: std::vector takeTopLevelDecls() { return std::move(TopLevelDecls); } - std::vector takeTopLevelDeclIDs() { + std::vector takeTopLevelDeclIDs() { return std::move(TopLevelDeclIDs); } @@ -1101,7 +1101,7 @@ public: private: unsigned Hash = 0; std::vector TopLevelDecls; - std::vector TopLevelDeclIDs; + std::vector TopLevelDeclIDs; llvm::SmallVector PreambleDiags; }; @@ -1471,7 +1471,9 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() { for (const auto TopLevelDecl : TopLevelDeclsInPreamble) { // Resolve the declaration ID to an actual declaration, possibly // deserializing the declaration in the process. - if (Decl *D = Source.GetExternalDecl(TopLevelDecl)) + // + // FIMXE: We shouldn't convert a LocalDeclID to GlobalDeclID directly. + if (Decl *D = Source.GetExternalDecl(GlobalDeclID(TopLevelDecl.get()))) Resolved.push_back(D); } TopLevelDeclsInPreamble.clear(); diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 91ce16e5e795..a2af738a053e 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -80,7 +80,7 @@ public: if (Previous) Previous->TypeRead(Idx, T); } - void DeclRead(DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { if (Previous) Previous->DeclRead(ID, D); } @@ -102,7 +102,7 @@ public: bool DeletePrevious) : DelegatingDeserializationListener(Previous, DeletePrevious) {} - void DeclRead(DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { llvm::outs() << "PCH DECL: " << D->getDeclKindName(); if (const NamedDecl *ND = dyn_cast(D)) { llvm::outs() << " - "; @@ -128,7 +128,7 @@ public: : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx), NamesToCheck(NamesToCheck) {} - void DeclRead(DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { if (const NamedDecl *ND = dyn_cast(D)) if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { unsigned DiagID diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index 9e885c8dc0f6..c74bfd86195f 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -52,7 +52,8 @@ void MultiplexASTDeserializationListener::TypeRead( Listeners[i]->TypeRead(Idx, T); } -void MultiplexASTDeserializationListener::DeclRead(DeclID ID, const Decl *D) { +void MultiplexASTDeserializationListener::DeclRead(GlobalDeclID ID, + const Decl *D) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->DeclRead(ID, D); } diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index e48c72498389..79e656eb4b7e 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -46,7 +46,7 @@ void MultiplexExternalSemaSource::AddSource(ExternalSemaSource *Source) { // ExternalASTSource. //===----------------------------------------------------------------------===// -Decl *MultiplexExternalSemaSource::GetExternalDecl(DeclID ID) { +Decl *MultiplexExternalSemaSource::GetExternalDecl(GlobalDeclID ID) { for(size_t i = 0; i < Sources.size(); ++i) if (Decl *Result = Sources[i]->GetExternalDecl(ID)) return Result; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index df9984d537bf..c99d6ed1c36c 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -5101,8 +5101,9 @@ void ASTReader::InitializeContext() { // If there's a listener, notify them that we "read" the translation unit. if (DeserializationListener) - DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, - Context.getTranslationUnitDecl()); + DeserializationListener->DeclRead( + GlobalDeclID(PREDEF_DECL_TRANSLATION_UNIT_ID), + Context.getTranslationUnitDecl()); // FIXME: Find a better way to deal with collisions between these // built-in types. Right now, we just ignore the problem. @@ -6010,9 +6011,9 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F, case SUBMODULE_INITIALIZERS: { if (!ContextObj) break; - SmallVector Inits; + SmallVector Inits; for (auto &ID : Record) - Inits.push_back(getGlobalDeclID(F, LocalDeclID(ID)).get()); + Inits.push_back(getGlobalDeclID(F, LocalDeclID(ID))); ContextObj->addLazyModuleInitializers(CurrentModule, Inits); break; } @@ -7517,9 +7518,7 @@ ASTRecordReader::readASTTemplateArgumentListInfo() { return ASTTemplateArgumentListInfo::Create(getContext(), Result); } -Decl *ASTReader::GetExternalDecl(DeclID ID) { - return GetDecl(GlobalDeclID(ID)); -} +Decl *ASTReader::GetExternalDecl(GlobalDeclID ID) { return GetDecl(ID); } void ASTReader::CompleteRedeclChain(const Decl *D) { if (NumCurrentElementsDeserializing) { @@ -7767,7 +7766,7 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { assert(ContextObj && "reading decl with no AST context"); if (ID.get() < NUM_PREDEF_DECL_IDS) { - Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID.get()); + Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID); if (D) { // Track that we have merged the declaration with ID \p ID into the // pre-existing predefined declaration \p D. @@ -7804,17 +7803,17 @@ Decl *ASTReader::GetDecl(GlobalDeclID ID) { if (!DeclsLoaded[Index]) { ReadDeclRecord(ID); if (DeserializationListener) - DeserializationListener->DeclRead(ID.get(), DeclsLoaded[Index]); + DeserializationListener->DeclRead(ID, DeclsLoaded[Index]); } return DeclsLoaded[Index]; } -DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, - GlobalDeclID GlobalID) { +LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + GlobalDeclID GlobalID) { DeclID ID = GlobalID.get(); if (ID < NUM_PREDEF_DECL_IDS) - return ID; + return LocalDeclID(ID); GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID); assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); @@ -7823,9 +7822,9 @@ DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, llvm::DenseMap::iterator Pos = M.GlobalToLocalDeclIDs.find(Owner); if (Pos == M.GlobalToLocalDeclIDs.end()) - return 0; + return LocalDeclID(); - return ID - Owner->BaseDeclID + Pos->second; + return LocalDeclID(ID - Owner->BaseDeclID + Pos->second); } GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordData &Record, @@ -7992,6 +7991,7 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, // Load the list of declarations. SmallVector Decls; llvm::SmallPtrSet Found; + for (GlobalDeclID ID : It->second.Table.find(Name)) { NamedDecl *ND = cast(GetDecl(ID)); if (ND->getDeclName() == Name && Found.insert(ND).second) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 9707eed701e9..744f11de88c2 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -273,17 +273,15 @@ namespace clang { auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations; if (auto &Old = LazySpecializations) { - IDs.insert(IDs.end(), GlobalDeclIDIterator(Old + 1), - GlobalDeclIDIterator(Old + 1 + Old[0])); + IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0].get()); llvm::sort(IDs); IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); } - auto *Result = new (C) DeclID[1 + IDs.size()]; - *Result = IDs.size(); + auto *Result = new (C) GlobalDeclID[1 + IDs.size()]; + *Result = GlobalDeclID(IDs.size()); - std::copy(DeclIDIterator(IDs.begin()), DeclIDIterator(IDs.end()), - Result + 1); + std::copy(IDs.begin(), IDs.end(), Result + 1); LazySpecializations = Result; } @@ -558,7 +556,7 @@ void ASTDeclReader::Visit(Decl *D) { // If this is a tag declaration with a typedef name for linkage, it's safe // to load that typedef now. - if (NamedDeclForTagDecl != GlobalDeclID()) + if (NamedDeclForTagDecl.isValid()) cast(D)->TypedefNameDeclOrQualifier = cast(Reader.GetDecl(NamedDeclForTagDecl)); } else if (auto *ID = dyn_cast(D)) { @@ -603,7 +601,7 @@ void ASTDeclReader::VisitDecl(Decl *D) { GlobalDeclID SemaDCIDForTemplateParmDecl = readDeclID(); GlobalDeclID LexicalDCIDForTemplateParmDecl = HasStandaloneLexicalDC ? readDeclID() : GlobalDeclID(); - if (LexicalDCIDForTemplateParmDecl == GlobalDeclID()) + if (LexicalDCIDForTemplateParmDecl.isInvalid()) LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl; Reader.addPendingDeclContextInfo(D, SemaDCIDForTemplateParmDecl, @@ -1860,7 +1858,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { mergeRedeclarable(D, Redecl); - if (AnonNamespace != GlobalDeclID()) { + if (AnonNamespace.isValid()) { // Each module has its own anonymous namespace, which is disjoint from // any other module's anonymous namespaces, so don't attach the anonymous // namespace at all. @@ -2792,9 +2790,9 @@ ASTDeclReader::VisitRedeclarable(Redeclarable *D) { uint64_t RedeclOffset = 0; - // 0 indicates that this declaration was the only declaration of its entity, - // and is used for space optimization. - if (FirstDeclID == GlobalDeclID()) { + // invalid FirstDeclID indicates that this declaration was the only + // declaration of its entity, and is used for space optimization. + if (FirstDeclID.isInvalid()) { FirstDeclID = ThisDeclID; IsKeyDecl = true; IsFirstLocalDecl = true; @@ -3829,240 +3827,232 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { Twine("ASTReader::readDeclRecord failed reading decl code: ") + toString(MaybeDeclCode.takeError())); - DeclID RawGlobalID = ID.get(); switch ((DeclCode)MaybeDeclCode.get()) { case DECL_CONTEXT_LEXICAL: case DECL_CONTEXT_VISIBLE: llvm_unreachable("Record cannot be de-serialized with readDeclRecord"); case DECL_TYPEDEF: - D = TypedefDecl::CreateDeserialized(Context, RawGlobalID); + D = TypedefDecl::CreateDeserialized(Context, ID); break; case DECL_TYPEALIAS: - D = TypeAliasDecl::CreateDeserialized(Context, RawGlobalID); + D = TypeAliasDecl::CreateDeserialized(Context, ID); break; case DECL_ENUM: - D = EnumDecl::CreateDeserialized(Context, RawGlobalID); + D = EnumDecl::CreateDeserialized(Context, ID); break; case DECL_RECORD: - D = RecordDecl::CreateDeserialized(Context, RawGlobalID); + D = RecordDecl::CreateDeserialized(Context, ID); break; case DECL_ENUM_CONSTANT: - D = EnumConstantDecl::CreateDeserialized(Context, RawGlobalID); + D = EnumConstantDecl::CreateDeserialized(Context, ID); break; case DECL_FUNCTION: - D = FunctionDecl::CreateDeserialized(Context, RawGlobalID); + D = FunctionDecl::CreateDeserialized(Context, ID); break; case DECL_LINKAGE_SPEC: - D = LinkageSpecDecl::CreateDeserialized(Context, RawGlobalID); + D = LinkageSpecDecl::CreateDeserialized(Context, ID); break; case DECL_EXPORT: - D = ExportDecl::CreateDeserialized(Context, RawGlobalID); + D = ExportDecl::CreateDeserialized(Context, ID); break; case DECL_LABEL: - D = LabelDecl::CreateDeserialized(Context, RawGlobalID); + D = LabelDecl::CreateDeserialized(Context, ID); break; case DECL_NAMESPACE: - D = NamespaceDecl::CreateDeserialized(Context, RawGlobalID); + D = NamespaceDecl::CreateDeserialized(Context, ID); break; case DECL_NAMESPACE_ALIAS: - D = NamespaceAliasDecl::CreateDeserialized(Context, RawGlobalID); + D = NamespaceAliasDecl::CreateDeserialized(Context, ID); break; case DECL_USING: - D = UsingDecl::CreateDeserialized(Context, RawGlobalID); + D = UsingDecl::CreateDeserialized(Context, ID); break; case DECL_USING_PACK: - D = UsingPackDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = UsingPackDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_USING_SHADOW: - D = UsingShadowDecl::CreateDeserialized(Context, RawGlobalID); + D = UsingShadowDecl::CreateDeserialized(Context, ID); break; case DECL_USING_ENUM: - D = UsingEnumDecl::CreateDeserialized(Context, RawGlobalID); + D = UsingEnumDecl::CreateDeserialized(Context, ID); break; case DECL_CONSTRUCTOR_USING_SHADOW: - D = ConstructorUsingShadowDecl::CreateDeserialized(Context, RawGlobalID); + D = ConstructorUsingShadowDecl::CreateDeserialized(Context, ID); break; case DECL_USING_DIRECTIVE: - D = UsingDirectiveDecl::CreateDeserialized(Context, RawGlobalID); + D = UsingDirectiveDecl::CreateDeserialized(Context, ID); break; case DECL_UNRESOLVED_USING_VALUE: - D = UnresolvedUsingValueDecl::CreateDeserialized(Context, RawGlobalID); + D = UnresolvedUsingValueDecl::CreateDeserialized(Context, ID); break; case DECL_UNRESOLVED_USING_TYPENAME: - D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, RawGlobalID); + D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, ID); break; case DECL_UNRESOLVED_USING_IF_EXISTS: - D = UnresolvedUsingIfExistsDecl::CreateDeserialized(Context, RawGlobalID); + D = UnresolvedUsingIfExistsDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_RECORD: - D = CXXRecordDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXRecordDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_DEDUCTION_GUIDE: - D = CXXDeductionGuideDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXDeductionGuideDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_METHOD: - D = CXXMethodDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXMethodDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_CONSTRUCTOR: - D = CXXConstructorDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = CXXConstructorDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_CXX_DESTRUCTOR: - D = CXXDestructorDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXDestructorDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_CONVERSION: - D = CXXConversionDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXConversionDecl::CreateDeserialized(Context, ID); break; case DECL_ACCESS_SPEC: - D = AccessSpecDecl::CreateDeserialized(Context, RawGlobalID); + D = AccessSpecDecl::CreateDeserialized(Context, ID); break; case DECL_FRIEND: - D = FriendDecl::CreateDeserialized(Context, RawGlobalID, Record.readInt()); + D = FriendDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_FRIEND_TEMPLATE: - D = FriendTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = FriendTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_CLASS_TEMPLATE: - D = ClassTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = ClassTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_CLASS_TEMPLATE_SPECIALIZATION: - D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, - RawGlobalID); + D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, ID); break; case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION: - D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, - RawGlobalID); + D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); break; case DECL_VAR_TEMPLATE: - D = VarTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = VarTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_VAR_TEMPLATE_SPECIALIZATION: - D = VarTemplateSpecializationDecl::CreateDeserialized(Context, RawGlobalID); + D = VarTemplateSpecializationDecl::CreateDeserialized(Context, ID); break; case DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION: - D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, - RawGlobalID); + D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); break; case DECL_FUNCTION_TEMPLATE: - D = FunctionTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = FunctionTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_TEMPLATE_TYPE_PARM: { bool HasTypeConstraint = Record.readInt(); - D = TemplateTypeParmDecl::CreateDeserialized(Context, RawGlobalID, + D = TemplateTypeParmDecl::CreateDeserialized(Context, ID, HasTypeConstraint); break; } case DECL_NON_TYPE_TEMPLATE_PARM: { bool HasTypeConstraint = Record.readInt(); - D = NonTypeTemplateParmDecl::CreateDeserialized(Context, RawGlobalID, + D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, HasTypeConstraint); break; } case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: { bool HasTypeConstraint = Record.readInt(); D = NonTypeTemplateParmDecl::CreateDeserialized( - Context, RawGlobalID, Record.readInt(), HasTypeConstraint); + Context, ID, Record.readInt(), HasTypeConstraint); break; } case DECL_TEMPLATE_TEMPLATE_PARM: - D = TemplateTemplateParmDecl::CreateDeserialized(Context, RawGlobalID); + D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID); break; case DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK: - D = TemplateTemplateParmDecl::CreateDeserialized(Context, RawGlobalID, + D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_TYPE_ALIAS_TEMPLATE: - D = TypeAliasTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_CONCEPT: - D = ConceptDecl::CreateDeserialized(Context, RawGlobalID); + D = ConceptDecl::CreateDeserialized(Context, ID); break; case DECL_REQUIRES_EXPR_BODY: - D = RequiresExprBodyDecl::CreateDeserialized(Context, RawGlobalID); + D = RequiresExprBodyDecl::CreateDeserialized(Context, ID); break; case DECL_STATIC_ASSERT: - D = StaticAssertDecl::CreateDeserialized(Context, RawGlobalID); + D = StaticAssertDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_METHOD: - D = ObjCMethodDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCMethodDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_INTERFACE: - D = ObjCInterfaceDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCInterfaceDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_IVAR: - D = ObjCIvarDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCIvarDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_PROTOCOL: - D = ObjCProtocolDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCProtocolDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_AT_DEFS_FIELD: - D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_CATEGORY: - D = ObjCCategoryDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCCategoryDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_CATEGORY_IMPL: - D = ObjCCategoryImplDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCCategoryImplDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_IMPLEMENTATION: - D = ObjCImplementationDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCImplementationDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_COMPATIBLE_ALIAS: - D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_PROPERTY: - D = ObjCPropertyDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCPropertyDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_PROPERTY_IMPL: - D = ObjCPropertyImplDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCPropertyImplDecl::CreateDeserialized(Context, ID); break; case DECL_FIELD: - D = FieldDecl::CreateDeserialized(Context, RawGlobalID); + D = FieldDecl::CreateDeserialized(Context, ID); break; case DECL_INDIRECTFIELD: - D = IndirectFieldDecl::CreateDeserialized(Context, RawGlobalID); + D = IndirectFieldDecl::CreateDeserialized(Context, ID); break; case DECL_VAR: - D = VarDecl::CreateDeserialized(Context, RawGlobalID); + D = VarDecl::CreateDeserialized(Context, ID); break; case DECL_IMPLICIT_PARAM: - D = ImplicitParamDecl::CreateDeserialized(Context, RawGlobalID); + D = ImplicitParamDecl::CreateDeserialized(Context, ID); break; case DECL_PARM_VAR: - D = ParmVarDecl::CreateDeserialized(Context, RawGlobalID); + D = ParmVarDecl::CreateDeserialized(Context, ID); break; case DECL_DECOMPOSITION: - D = DecompositionDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = DecompositionDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_BINDING: - D = BindingDecl::CreateDeserialized(Context, RawGlobalID); + D = BindingDecl::CreateDeserialized(Context, ID); break; case DECL_FILE_SCOPE_ASM: - D = FileScopeAsmDecl::CreateDeserialized(Context, RawGlobalID); + D = FileScopeAsmDecl::CreateDeserialized(Context, ID); break; case DECL_TOP_LEVEL_STMT_DECL: - D = TopLevelStmtDecl::CreateDeserialized(Context, RawGlobalID); + D = TopLevelStmtDecl::CreateDeserialized(Context, ID); break; case DECL_BLOCK: - D = BlockDecl::CreateDeserialized(Context, RawGlobalID); + D = BlockDecl::CreateDeserialized(Context, ID); break; case DECL_MS_PROPERTY: - D = MSPropertyDecl::CreateDeserialized(Context, RawGlobalID); + D = MSPropertyDecl::CreateDeserialized(Context, ID); break; case DECL_MS_GUID: - D = MSGuidDecl::CreateDeserialized(Context, RawGlobalID); + D = MSGuidDecl::CreateDeserialized(Context, ID); break; case DECL_UNNAMED_GLOBAL_CONSTANT: - D = UnnamedGlobalConstantDecl::CreateDeserialized(Context, RawGlobalID); + D = UnnamedGlobalConstantDecl::CreateDeserialized(Context, ID); break; case DECL_TEMPLATE_PARAM_OBJECT: - D = TemplateParamObjectDecl::CreateDeserialized(Context, RawGlobalID); + D = TemplateParamObjectDecl::CreateDeserialized(Context, ID); break; case DECL_CAPTURED: - D = CapturedDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = CapturedDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_CXX_BASE_SPECIFIERS: Error("attempt to read a C++ base-specifier record as a declaration"); @@ -4073,66 +4063,62 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { case DECL_IMPORT: // Note: last entry of the ImportDecl record is the number of stored source // locations. - D = ImportDecl::CreateDeserialized(Context, RawGlobalID, Record.back()); + D = ImportDecl::CreateDeserialized(Context, ID, Record.back()); break; case DECL_OMP_THREADPRIVATE: { Record.skipInts(1); unsigned NumChildren = Record.readInt(); Record.skipInts(1); - D = OMPThreadPrivateDecl::CreateDeserialized(Context, RawGlobalID, - NumChildren); + D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, NumChildren); break; } case DECL_OMP_ALLOCATE: { unsigned NumClauses = Record.readInt(); unsigned NumVars = Record.readInt(); Record.skipInts(1); - D = OMPAllocateDecl::CreateDeserialized(Context, RawGlobalID, NumVars, - NumClauses); + D = OMPAllocateDecl::CreateDeserialized(Context, ID, NumVars, NumClauses); break; } case DECL_OMP_REQUIRES: { unsigned NumClauses = Record.readInt(); Record.skipInts(2); - D = OMPRequiresDecl::CreateDeserialized(Context, RawGlobalID, NumClauses); + D = OMPRequiresDecl::CreateDeserialized(Context, ID, NumClauses); break; } case DECL_OMP_DECLARE_REDUCTION: - D = OMPDeclareReductionDecl::CreateDeserialized(Context, RawGlobalID); + D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID); break; case DECL_OMP_DECLARE_MAPPER: { unsigned NumClauses = Record.readInt(); Record.skipInts(2); - D = OMPDeclareMapperDecl::CreateDeserialized(Context, RawGlobalID, - NumClauses); + D = OMPDeclareMapperDecl::CreateDeserialized(Context, ID, NumClauses); break; } case DECL_OMP_CAPTUREDEXPR: - D = OMPCapturedExprDecl::CreateDeserialized(Context, RawGlobalID); + D = OMPCapturedExprDecl::CreateDeserialized(Context, ID); break; case DECL_PRAGMA_COMMENT: - D = PragmaCommentDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = PragmaCommentDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_PRAGMA_DETECT_MISMATCH: - D = PragmaDetectMismatchDecl::CreateDeserialized(Context, RawGlobalID, + D = PragmaDetectMismatchDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_EMPTY: - D = EmptyDecl::CreateDeserialized(Context, RawGlobalID); + D = EmptyDecl::CreateDeserialized(Context, ID); break; case DECL_LIFETIME_EXTENDED_TEMPORARY: - D = LifetimeExtendedTemporaryDecl::CreateDeserialized(Context, RawGlobalID); + D = LifetimeExtendedTemporaryDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_TYPE_PARAM: - D = ObjCTypeParamDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCTypeParamDecl::CreateDeserialized(Context, ID); break; case DECL_HLSL_BUFFER: - D = HLSLBufferDecl::CreateDeserialized(Context, RawGlobalID); + D = HLSLBufferDecl::CreateDeserialized(Context, ID); break; case DECL_IMPLICIT_CONCEPT_SPECIALIZATION: - D = ImplicitConceptSpecializationDecl::CreateDeserialized( - Context, RawGlobalID, Record.readInt()); + D = ImplicitConceptSpecializationDecl::CreateDeserialized(Context, ID, + Record.readInt()); break; } @@ -4424,8 +4410,9 @@ namespace { // Map global ID of the definition down to the local ID used in this // module file. If there is no such mapping, we'll find nothing here // (or in any module it imports). - DeclID LocalID = Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID); - if (!LocalID) + LocalDeclID LocalID = + Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID); + if (LocalID.isInvalid()) return true; // Perform a binary search to find the local redeclarations for this diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 842ea58656ad..0408eeb6a95b 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3043,7 +3043,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { RecordData Inits; for (Decl *D : Context->getModuleInitializers(Mod)) if (wasDeclEmitted(D)) - Inits.push_back(GetDeclRef(D)); + AddDeclRef(D, Inits); if (!Inits.empty()) Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits); @@ -3226,7 +3226,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, continue; KindDeclPairs.push_back(D->getKind()); - KindDeclPairs.push_back(GetDeclRef(D)); + KindDeclPairs.push_back(GetDeclRef(D).get()); } ++NumLexicalDeclContexts; @@ -3261,7 +3261,7 @@ void ASTWriter::WriteTypeDeclOffsets() { unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); { RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(), - FirstDeclID - NUM_PREDEF_DECL_IDS}; + FirstDeclID.get() - NUM_PREDEF_DECL_IDS}; Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets)); } } @@ -3282,7 +3282,7 @@ void ASTWriter::WriteFileDeclIDsMap() { Info.FirstDeclIndex = FileGroupedDeclIDs.size(); llvm::stable_sort(Info.DeclIDs); for (auto &LocDeclEntry : Info.DeclIDs) - FileGroupedDeclIDs.push_back(LocDeclEntry.second); + FileGroupedDeclIDs.push_back(LocDeclEntry.second.get()); } auto Abbrev = std::make_shared(); @@ -3420,11 +3420,11 @@ public: for (const ObjCMethodList *Method = &Methods.Instance; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - LE.write(Writer.getDeclID(Method->getMethod())); + LE.write((DeclID)Writer.getDeclID(Method->getMethod())); for (const ObjCMethodList *Method = &Methods.Factory; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - LE.write(Writer.getDeclID(Method->getMethod())); + LE.write((DeclID)Writer.getDeclID(Method->getMethod())); assert(Out.tell() - Start == DataLen && "Data length is wrong"); } @@ -3743,8 +3743,8 @@ public: // Only emit declarations that aren't from a chained PCH, though. SmallVector Decls(IdResolver.decls(II)); for (NamedDecl *D : llvm::reverse(Decls)) - LE.write( - Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), D))); + LE.write((DeclID)Writer.getDeclID( + getDeclForLocalLookup(PP.getLangOpts(), D))); } } }; @@ -3860,7 +3860,7 @@ namespace { // Trait used for the on-disk hash table used in the method pool. class ASTDeclContextNameLookupTrait { ASTWriter &Writer; - llvm::SmallVector DeclIDs; + llvm::SmallVector DeclIDs; public: using key_type = DeclarationNameKey; @@ -3893,8 +3893,10 @@ public: data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) { unsigned Start = DeclIDs.size(); - DeclIDs.insert(DeclIDs.end(), DeclIDIterator(FromReader.begin()), - DeclIDIterator(FromReader.end())); + DeclIDs.insert( + DeclIDs.end(), + DeclIDIterator(FromReader.begin()), + DeclIDIterator(FromReader.end())); return std::make_pair(Start, DeclIDs.size()); } @@ -3983,7 +3985,7 @@ public: endian::Writer LE(Out, llvm::endianness::little); uint64_t Start = Out.tell(); (void)Start; for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) - LE.write(DeclIDs[I]); + LE.write((DeclID)DeclIDs[I]); assert(Out.tell() - Start == DataLen && "Data length is wrong"); } }; @@ -4317,7 +4319,8 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { DC = cast(Chain->getKeyDeclaration(cast(DC))); // Write the lookup table - RecordData::value_type Record[] = {UPDATE_VISIBLE, getDeclID(cast(DC))}; + RecordData::value_type Record[] = {UPDATE_VISIBLE, + getDeclID(cast(DC)).get()}; Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable); } @@ -4371,7 +4374,7 @@ void ASTWriter::WriteObjCCategories() { Cat = Class->known_categories_begin(), CatEnd = Class->known_categories_end(); Cat != CatEnd; ++Cat, ++Size) { - assert(getDeclID(*Cat) != 0 && "Bogus category"); + assert(getDeclID(*Cat).isValid() && "Bogus category"); AddDeclRef(*Cat, Categories); } @@ -5089,7 +5092,7 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) { if (!D || !wasDeclEmitted(D)) SemaDeclRefs.push_back(0); else - SemaDeclRefs.push_back(getDeclID(D)); + AddDeclRef(D, SemaDeclRefs); }; AddEmittedDeclRefOrZero(SemaRef.getStdNamespace()); @@ -5100,10 +5103,10 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) { Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); // Write the record containing decls to be checked for deferred diags. - SmallVector DeclsToCheckForDeferredDiags; + RecordData DeclsToCheckForDeferredDiags; for (auto *D : SemaRef.DeclsToCheckForDeferredDiags) if (wasDeclEmitted(D)) - DeclsToCheckForDeferredDiags.push_back(getDeclID(D)); + AddDeclRef(D, DeclsToCheckForDeferredDiags); if (!DeclsToCheckForDeferredDiags.empty()) Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS, DeclsToCheckForDeferredDiags); @@ -5473,7 +5476,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { if (VisibleOffset) VisibleOffset -= DeclTypesBlockStartOffset; - DelayedNamespaceRecord.push_back(getDeclID(NS)); + AddDeclRef(NS, DelayedNamespaceRecord); DelayedNamespaceRecord.push_back(LexicalOffset); DelayedNamespaceRecord.push_back(VisibleOffset); } @@ -5507,7 +5510,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { continue; NewGlobalKindDeclPairs.push_back(D->getKind()); - NewGlobalKindDeclPairs.push_back(GetDeclRef(D)); + NewGlobalKindDeclPairs.push_back(GetDeclRef(D).get()); } auto Abv = std::make_shared(); @@ -5568,7 +5571,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: assert(Update.getDecl() && "no decl to add?"); - Record.push_back(GetDeclRef(Update.getDecl())); + Record.AddDeclRef(Update.getDecl()); break; case UPD_CXX_ADDED_FUNCTION_DEFINITION: @@ -5709,7 +5712,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { } } - OffsetsRecord.push_back(GetDeclRef(D)); + AddDeclRef(D, OffsetsRecord); OffsetsRecord.push_back(Record.Emit(DECL_UPDATES)); } } @@ -5974,18 +5977,18 @@ void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) { if (!wasDeclEmitted(D)) return; - Record.push_back(GetDeclRef(D)); + Record.push_back(GetDeclRef(D).get()); } void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { - Record.push_back(GetDeclRef(D)); + Record.push_back(GetDeclRef(D).get()); } -DeclID ASTWriter::GetDeclRef(const Decl *D) { +LocalDeclID ASTWriter::GetDeclRef(const Decl *D) { assert(WritingAST && "Cannot request a declaration ID before AST writing"); if (!D) { - return 0; + return LocalDeclID(); } // If the DeclUpdate from the GMF gets touched, emit it. @@ -5999,14 +6002,14 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) { // If D comes from an AST file, its declaration ID is already known and // fixed. if (D->isFromASTFile()) - return D->getGlobalID(); + return LocalDeclID(D->getGlobalID()); assert(!(reinterpret_cast(D) & 0x01) && "Invalid decl pointer"); - DeclID &ID = DeclIDs[D]; - if (ID == 0) { + LocalDeclID &ID = DeclIDs[D]; + if (ID.isInvalid()) { if (DoneWritingDeclsAndTypes) { assert(0 && "New decl seen after serializing all the decls to emit!"); - return 0; + return LocalDeclID(); } // We haven't seen this declaration before. Give it a new ID and @@ -6018,14 +6021,14 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) { return ID; } -DeclID ASTWriter::getDeclID(const Decl *D) { +LocalDeclID ASTWriter::getDeclID(const Decl *D) { if (!D) - return 0; + return LocalDeclID(); // If D comes from an AST file, its declaration ID is already known and // fixed. if (D->isFromASTFile()) - return D->getGlobalID(); + return LocalDeclID(D->getGlobalID()); assert(DeclIDs.contains(D) && "Declaration not emitted!"); return DeclIDs[D]; @@ -6046,8 +6049,8 @@ bool ASTWriter::wasDeclEmitted(const Decl *D) const { return Emitted; } -void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { - assert(ID); +void ASTWriter::associateDeclWithFile(const Decl *D, LocalDeclID ID) { + assert(ID.isValid()); assert(D); SourceLocation Loc = D->getLocation(); @@ -6079,7 +6082,7 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { if (!Info) Info = std::make_unique(); - std::pair LocDecl(Offset, ID); + std::pair LocDecl(Offset, ID); LocDeclIDsTy &Decls = Info->DeclIDs; Decls.push_back(LocDecl); } @@ -6349,7 +6352,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType(); Record->push_back(ModulesDebugInfo); if (ModulesDebugInfo) - Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D)); + Writer->AddDeclRef(D, Writer->ModularCodegenDecls); // IsLambda bit is already saved. @@ -6453,7 +6456,7 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { // Note, this will get called multiple times, once one the reader starts up // and again each time it's done reading a PCH or module. - FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls(); + FirstDeclID = LocalDeclID(NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls()); FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros(); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index fe867192b717..0edc4feda3ef 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -223,9 +223,9 @@ namespace clang { assert(!Common->LazySpecializations); } - ArrayRef LazySpecializations; + ArrayRef LazySpecializations; if (auto *LS = Common->LazySpecializations) - LazySpecializations = llvm::ArrayRef(LS + 1, LS[0]); + LazySpecializations = llvm::ArrayRef(LS + 1, LS[0].get()); // Add a slot to the record for the number of specializations. unsigned I = Record.size(); @@ -243,7 +243,9 @@ namespace clang { assert(D->isCanonicalDecl() && "non-canonical decl in set"); AddFirstDeclFromEachModule(D, /*IncludeLocal*/true); } - Record.append(LazySpecializations.begin(), LazySpecializations.end()); + Record.append( + DeclIDIterator(LazySpecializations.begin()), + DeclIDIterator(LazySpecializations.end())); // Update the size entry we added earlier. Record[I] = Record.size() - I - 1; @@ -1166,7 +1168,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(VarDeclBits); if (ModulesCodegen) - Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D)); + Writer.AddDeclRef(D, Writer.ModularCodegenDecls); if (D->hasAttr()) { BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D); @@ -2786,10 +2788,10 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { "serializing"); // Determine the ID for this declaration. - DeclID ID; + LocalDeclID ID; assert(!D->isFromASTFile() && "should not be emitting imported decl"); - DeclID &IDR = DeclIDs[D]; - if (IDR == 0) + LocalDeclID &IDR = DeclIDs[D]; + if (IDR.isInvalid()) IDR = NextDeclID++; ID = IDR; @@ -2807,7 +2809,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Record the offset for this declaration SourceLocation Loc = D->getLocation(); - unsigned Index = ID - FirstDeclID; + unsigned Index = ID.get() - FirstDeclID.get(); if (DeclOffsets.size() == Index) DeclOffsets.emplace_back(getAdjustedLocation(Loc), Offset, DeclTypesBlockStartOffset); @@ -2827,7 +2829,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Note declarations that should be deserialized eagerly so that we can add // them to a record in the AST file later. if (isRequiredDecl(D, Context, WritingModule)) - EagerlyDeserializedDecls.push_back(ID); + AddDeclRef(D, EagerlyDeserializedDecls); } void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { @@ -2863,7 +2865,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { } Record->push_back(ModulesCodegen); if (ModulesCodegen) - Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(FD)); + Writer->AddDeclRef(FD, Writer->ModularCodegenDecls); if (auto *CD = dyn_cast(FD)) { Record->push_back(CD->getNumCtorInitializers()); if (CD->getNumCtorInitializers()) -- GitLab From 2c9e2e9f0b75d6b023a388564092cc852ba29bd5 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Thu, 25 Apr 2024 14:22:14 +0800 Subject: [PATCH 056/733] [RISCV][ISel] Eliminate `andi rd, rs1, -1` instructions (#89976) Inspired by https://github.com/llvm/llvm-project/pull/89966, this patch handles the special case `binop_allwusers GPR:$rs1, 0xffffffff -> copy $rs1` to avoid creating redundant `andi rd, rs1, -1` instructions. --- llvm/lib/Target/RISCV/RISCVInstrInfo.td | 2 + .../CodeGen/RISCV/rv64-legal-i32/rv64zba.ll | 6 - .../RISCV/rv64-legal-i32/rv64zbb-zbkb.ll | 58 ++--- .../test/CodeGen/RISCV/rv64i-demanded-bits.ll | 14 ++ llvm/test/CodeGen/RISCV/rv64zba.ll | 6 - .../rvv/fixed-vectors-reduction-int-vp.ll | 104 +++----- .../CodeGen/RISCV/rvv/vreductions-int-vp.ll | 230 ++++++------------ llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll | 1 - 8 files changed, 146 insertions(+), 275 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index f9dadc6c0d48..da4020758eb6 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1813,6 +1813,8 @@ def : Pat<(binop_allwusers (sext_inreg GPR:$rs1, i32), uimm5:$shamt), // Use binop_allwusers to recover immediates that may have been broken by // SimplifyDemandedBits. +def : Pat<(binop_allwusers GPR:$rs1, 0xffffffff), + (COPY GPR:$rs1)>; def : Pat<(binop_allwusers GPR:$rs1, u32simm12:$imm), (ANDI GPR:$rs1, u32simm12:$imm)>; diff --git a/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll index 9f06a9dd124c..c3ae40124ba0 100644 --- a/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll +++ b/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll @@ -634,7 +634,6 @@ define i64 @zext_mul288(i32 signext %a) { } ; We can't use slli.uw becaues the shift amount is more than 31. -; FIXME: The zext.w is unneeded. define i64 @zext_mul12884901888(i32 signext %a) { ; RV64I-LABEL: zext_mul12884901888: ; RV64I: # %bb.0: @@ -647,7 +646,6 @@ define i64 @zext_mul12884901888(i32 signext %a) { ; ; RV64ZBA-LABEL: zext_mul12884901888: ; RV64ZBA: # %bb.0: -; RV64ZBA-NEXT: andi a0, a0, -1 ; RV64ZBA-NEXT: sh1add a0, a0, a0 ; RV64ZBA-NEXT: slli a0, a0, 32 ; RV64ZBA-NEXT: ret @@ -657,7 +655,6 @@ define i64 @zext_mul12884901888(i32 signext %a) { } ; We can't use slli.uw becaues the shift amount is more than 31. -; FIXME: The zext.w is unneeded. define i64 @zext_mul21474836480(i32 signext %a) { ; RV64I-LABEL: zext_mul21474836480: ; RV64I: # %bb.0: @@ -670,7 +667,6 @@ define i64 @zext_mul21474836480(i32 signext %a) { ; ; RV64ZBA-LABEL: zext_mul21474836480: ; RV64ZBA: # %bb.0: -; RV64ZBA-NEXT: andi a0, a0, -1 ; RV64ZBA-NEXT: sh2add a0, a0, a0 ; RV64ZBA-NEXT: slli a0, a0, 32 ; RV64ZBA-NEXT: ret @@ -680,7 +676,6 @@ define i64 @zext_mul21474836480(i32 signext %a) { } ; We can't use slli.uw becaues the shift amount is more than 31. -; FIXME: The zext.w is unneeded. define i64 @zext_mul38654705664(i32 signext %a) { ; RV64I-LABEL: zext_mul38654705664: ; RV64I: # %bb.0: @@ -693,7 +688,6 @@ define i64 @zext_mul38654705664(i32 signext %a) { ; ; RV64ZBA-LABEL: zext_mul38654705664: ; RV64ZBA: # %bb.0: -; RV64ZBA-NEXT: andi a0, a0, -1 ; RV64ZBA-NEXT: sh3add a0, a0, a0 ; RV64ZBA-NEXT: slli a0, a0, 32 ; RV64ZBA-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbb-zbkb.ll index 39a5b9b0f367..c98ad4592a66 100644 --- a/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbb-zbkb.ll +++ b/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbb-zbkb.ll @@ -102,11 +102,10 @@ declare i32 @llvm.fshl.i32(i32, i32, i32) define signext i32 @rol_i32(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: rol_i32: ; RV64I: # %bb.0: -; RV64I-NEXT: andi a2, a1, -1 -; RV64I-NEXT: sllw a1, a0, a1 -; RV64I-NEXT: negw a2, a2 -; RV64I-NEXT: srlw a0, a0, a2 -; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: sllw a2, a0, a1 +; RV64I-NEXT: negw a1, a1 +; RV64I-NEXT: srlw a0, a0, a1 +; RV64I-NEXT: or a0, a2, a0 ; RV64I-NEXT: ret ; ; RV64ZBB-ZBKB-LABEL: rol_i32: @@ -121,11 +120,10 @@ define signext i32 @rol_i32(i32 signext %a, i32 signext %b) nounwind { define void @rol_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind { ; RV64I-LABEL: rol_i32_nosext: ; RV64I: # %bb.0: -; RV64I-NEXT: andi a3, a1, -1 -; RV64I-NEXT: sllw a1, a0, a1 -; RV64I-NEXT: negw a3, a3 -; RV64I-NEXT: srlw a0, a0, a3 -; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: sllw a3, a0, a1 +; RV64I-NEXT: negw a1, a1 +; RV64I-NEXT: srlw a0, a0, a1 +; RV64I-NEXT: or a0, a3, a0 ; RV64I-NEXT: sw a0, 0(a2) ; RV64I-NEXT: ret ; @@ -142,12 +140,11 @@ define void @rol_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind { define signext i32 @rol_i32_neg_constant_rhs(i32 signext %a) nounwind { ; RV64I-LABEL: rol_i32_neg_constant_rhs: ; RV64I: # %bb.0: -; RV64I-NEXT: andi a1, a0, -1 -; RV64I-NEXT: li a2, -2 -; RV64I-NEXT: sllw a0, a2, a0 -; RV64I-NEXT: negw a1, a1 -; RV64I-NEXT: srlw a1, a2, a1 -; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: li a1, -2 +; RV64I-NEXT: sllw a2, a1, a0 +; RV64I-NEXT: negw a0, a0 +; RV64I-NEXT: srlw a0, a1, a0 +; RV64I-NEXT: or a0, a2, a0 ; RV64I-NEXT: ret ; ; RV64ZBB-ZBKB-LABEL: rol_i32_neg_constant_rhs: @@ -183,11 +180,10 @@ declare i32 @llvm.fshr.i32(i32, i32, i32) define signext i32 @ror_i32(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: ror_i32: ; RV64I: # %bb.0: -; RV64I-NEXT: andi a2, a1, -1 -; RV64I-NEXT: srlw a1, a0, a1 -; RV64I-NEXT: negw a2, a2 -; RV64I-NEXT: sllw a0, a0, a2 -; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: srlw a2, a0, a1 +; RV64I-NEXT: negw a1, a1 +; RV64I-NEXT: sllw a0, a0, a1 +; RV64I-NEXT: or a0, a2, a0 ; RV64I-NEXT: ret ; ; RV64ZBB-ZBKB-LABEL: ror_i32: @@ -202,11 +198,10 @@ define signext i32 @ror_i32(i32 signext %a, i32 signext %b) nounwind { define void @ror_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind { ; RV64I-LABEL: ror_i32_nosext: ; RV64I: # %bb.0: -; RV64I-NEXT: andi a3, a1, -1 -; RV64I-NEXT: srlw a1, a0, a1 -; RV64I-NEXT: negw a3, a3 -; RV64I-NEXT: sllw a0, a0, a3 -; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: srlw a3, a0, a1 +; RV64I-NEXT: negw a1, a1 +; RV64I-NEXT: sllw a0, a0, a1 +; RV64I-NEXT: or a0, a3, a0 ; RV64I-NEXT: sw a0, 0(a2) ; RV64I-NEXT: ret ; @@ -223,12 +218,11 @@ define void @ror_i32_nosext(i32 signext %a, i32 signext %b, ptr %x) nounwind { define signext i32 @ror_i32_neg_constant_rhs(i32 signext %a) nounwind { ; RV64I-LABEL: ror_i32_neg_constant_rhs: ; RV64I: # %bb.0: -; RV64I-NEXT: andi a1, a0, -1 -; RV64I-NEXT: li a2, -2 -; RV64I-NEXT: srlw a0, a2, a0 -; RV64I-NEXT: negw a1, a1 -; RV64I-NEXT: sllw a1, a2, a1 -; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: li a1, -2 +; RV64I-NEXT: srlw a2, a1, a0 +; RV64I-NEXT: negw a0, a0 +; RV64I-NEXT: sllw a0, a1, a0 +; RV64I-NEXT: or a0, a2, a0 ; RV64I-NEXT: ret ; ; RV64ZBB-ZBKB-LABEL: ror_i32_neg_constant_rhs: diff --git a/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll b/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll index 6a441e2b9f67..b8c43289bdfe 100644 --- a/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll +++ b/llvm/test/CodeGen/RISCV/rv64i-demanded-bits.ll @@ -192,3 +192,17 @@ entry: %or = or i32 %and, 255 ret i32 %or } + +define i64 @and_allones(i32 signext %x) { +; CHECK-LABEL: and_allones: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi a0, a0, -1 +; CHECK-NEXT: li a1, 1 +; CHECK-NEXT: sll a0, a1, a0 +; CHECK-NEXT: ret +entry: + %y = zext i32 %x to i64 + %shamt = add nsw i64 %y, -1 + %ret = shl i64 1, %shamt + ret i64 %ret +} diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll index 0efc45b99289..0745b59c06cc 100644 --- a/llvm/test/CodeGen/RISCV/rv64zba.ll +++ b/llvm/test/CodeGen/RISCV/rv64zba.ll @@ -851,7 +851,6 @@ define i64 @zext_mul288(i32 signext %a) { } ; We can't use slli.uw becaues the shift amount is more than 31. -; FIXME: The zext.w is unneeded. define i64 @zext_mul12884901888(i32 signext %a) { ; RV64I-LABEL: zext_mul12884901888: ; RV64I: # %bb.0: @@ -864,7 +863,6 @@ define i64 @zext_mul12884901888(i32 signext %a) { ; ; RV64ZBA-LABEL: zext_mul12884901888: ; RV64ZBA: # %bb.0: -; RV64ZBA-NEXT: andi a0, a0, -1 ; RV64ZBA-NEXT: sh1add a0, a0, a0 ; RV64ZBA-NEXT: slli a0, a0, 32 ; RV64ZBA-NEXT: ret @@ -874,7 +872,6 @@ define i64 @zext_mul12884901888(i32 signext %a) { } ; We can't use slli.uw becaues the shift amount is more than 31. -; FIXME: The zext.w is unneeded. define i64 @zext_mul21474836480(i32 signext %a) { ; RV64I-LABEL: zext_mul21474836480: ; RV64I: # %bb.0: @@ -887,7 +884,6 @@ define i64 @zext_mul21474836480(i32 signext %a) { ; ; RV64ZBA-LABEL: zext_mul21474836480: ; RV64ZBA: # %bb.0: -; RV64ZBA-NEXT: andi a0, a0, -1 ; RV64ZBA-NEXT: sh2add a0, a0, a0 ; RV64ZBA-NEXT: slli a0, a0, 32 ; RV64ZBA-NEXT: ret @@ -897,7 +893,6 @@ define i64 @zext_mul21474836480(i32 signext %a) { } ; We can't use slli.uw becaues the shift amount is more than 31. -; FIXME: The zext.w is unneeded. define i64 @zext_mul38654705664(i32 signext %a) { ; RV64I-LABEL: zext_mul38654705664: ; RV64I: # %bb.0: @@ -910,7 +905,6 @@ define i64 @zext_mul38654705664(i32 signext %a) { ; ; RV64ZBA-LABEL: zext_mul38654705664: ; RV64ZBA: # %bb.0: -; RV64ZBA-NEXT: andi a0, a0, -1 ; RV64ZBA-NEXT: sh3add a0, a0, a0 ; RV64ZBA-NEXT: slli a0, a0, 32 ; RV64ZBA-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int-vp.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int-vp.ll index 2495178ea762..02a989a96996 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int-vp.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-reduction-int-vp.ll @@ -574,24 +574,14 @@ define signext i32 @vpreduce_add_v2i32(i32 signext %s, <2 x i32> %v, <2 x i1> %m declare i32 @llvm.vp.reduce.umax.v2i32(i32, <2 x i32>, <2 x i1>, i32) define signext i32 @vpreduce_umax_v2i32(i32 signext %s, <2 x i32> %v, <2 x i1> %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umax_v2i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v9, a0 -; RV32-NEXT: vsetvli zero, a1, e32, mf2, ta, ma -; RV32-NEXT: vredmaxu.vs v9, v8, v9, v0.t -; RV32-NEXT: vmv.x.s a0, v9 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umax_v2i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v9, a0 -; RV64-NEXT: vsetvli zero, a1, e32, mf2, ta, ma -; RV64-NEXT: vredmaxu.vs v9, v8, v9, v0.t -; RV64-NEXT: vmv.x.s a0, v9 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umax_v2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v9, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, mf2, ta, ma +; CHECK-NEXT: vredmaxu.vs v9, v8, v9, v0.t +; CHECK-NEXT: vmv.x.s a0, v9 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umax.v2i32(i32 %s, <2 x i32> %v, <2 x i1> %m, i32 %evl) ret i32 %r } @@ -614,24 +604,14 @@ define signext i32 @vpreduce_smax_v2i32(i32 signext %s, <2 x i32> %v, <2 x i1> % declare i32 @llvm.vp.reduce.umin.v2i32(i32, <2 x i32>, <2 x i1>, i32) define signext i32 @vpreduce_umin_v2i32(i32 signext %s, <2 x i32> %v, <2 x i1> %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umin_v2i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v9, a0 -; RV32-NEXT: vsetvli zero, a1, e32, mf2, ta, ma -; RV32-NEXT: vredminu.vs v9, v8, v9, v0.t -; RV32-NEXT: vmv.x.s a0, v9 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umin_v2i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v9, a0 -; RV64-NEXT: vsetvli zero, a1, e32, mf2, ta, ma -; RV64-NEXT: vredminu.vs v9, v8, v9, v0.t -; RV64-NEXT: vmv.x.s a0, v9 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umin_v2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v9, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, mf2, ta, ma +; CHECK-NEXT: vredminu.vs v9, v8, v9, v0.t +; CHECK-NEXT: vmv.x.s a0, v9 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umin.v2i32(i32 %s, <2 x i32> %v, <2 x i1> %m, i32 %evl) ret i32 %r } @@ -714,24 +694,14 @@ define signext i32 @vpreduce_add_v4i32(i32 signext %s, <4 x i32> %v, <4 x i1> %m declare i32 @llvm.vp.reduce.umax.v4i32(i32, <4 x i32>, <4 x i1>, i32) define signext i32 @vpreduce_umax_v4i32(i32 signext %s, <4 x i32> %v, <4 x i1> %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umax_v4i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v9, a0 -; RV32-NEXT: vsetvli zero, a1, e32, m1, ta, ma -; RV32-NEXT: vredmaxu.vs v9, v8, v9, v0.t -; RV32-NEXT: vmv.x.s a0, v9 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umax_v4i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v9, a0 -; RV64-NEXT: vsetvli zero, a1, e32, m1, ta, ma -; RV64-NEXT: vredmaxu.vs v9, v8, v9, v0.t -; RV64-NEXT: vmv.x.s a0, v9 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umax_v4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v9, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma +; CHECK-NEXT: vredmaxu.vs v9, v8, v9, v0.t +; CHECK-NEXT: vmv.x.s a0, v9 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umax.v4i32(i32 %s, <4 x i32> %v, <4 x i1> %m, i32 %evl) ret i32 %r } @@ -754,24 +724,14 @@ define signext i32 @vpreduce_smax_v4i32(i32 signext %s, <4 x i32> %v, <4 x i1> % declare i32 @llvm.vp.reduce.umin.v4i32(i32, <4 x i32>, <4 x i1>, i32) define signext i32 @vpreduce_umin_v4i32(i32 signext %s, <4 x i32> %v, <4 x i1> %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umin_v4i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v9, a0 -; RV32-NEXT: vsetvli zero, a1, e32, m1, ta, ma -; RV32-NEXT: vredminu.vs v9, v8, v9, v0.t -; RV32-NEXT: vmv.x.s a0, v9 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umin_v4i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v9, a0 -; RV64-NEXT: vsetvli zero, a1, e32, m1, ta, ma -; RV64-NEXT: vredminu.vs v9, v8, v9, v0.t -; RV64-NEXT: vmv.x.s a0, v9 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umin_v4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v9, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma +; CHECK-NEXT: vredminu.vs v9, v8, v9, v0.t +; CHECK-NEXT: vmv.x.s a0, v9 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umin.v4i32(i32 %s, <4 x i32> %v, <4 x i1> %m, i32 %evl) ret i32 %r } diff --git a/llvm/test/CodeGen/RISCV/rvv/vreductions-int-vp.ll b/llvm/test/CodeGen/RISCV/rvv/vreductions-int-vp.ll index 618e169e1f96..7bcf37b1af3c 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vreductions-int-vp.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vreductions-int-vp.ll @@ -841,24 +841,14 @@ define signext i32 @vpreduce_add_nxv1i32(i32 signext %s, %v, declare i32 @llvm.vp.reduce.umax.nxv1i32(i32, , , i32) define signext i32 @vpreduce_umax_nxv1i32(i32 signext %s, %v, %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umax_nxv1i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v9, a0 -; RV32-NEXT: vsetvli zero, a1, e32, mf2, ta, ma -; RV32-NEXT: vredmaxu.vs v9, v8, v9, v0.t -; RV32-NEXT: vmv.x.s a0, v9 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umax_nxv1i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v9, a0 -; RV64-NEXT: vsetvli zero, a1, e32, mf2, ta, ma -; RV64-NEXT: vredmaxu.vs v9, v8, v9, v0.t -; RV64-NEXT: vmv.x.s a0, v9 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umax_nxv1i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v9, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, mf2, ta, ma +; CHECK-NEXT: vredmaxu.vs v9, v8, v9, v0.t +; CHECK-NEXT: vmv.x.s a0, v9 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umax.nxv1i32(i32 %s, %v, %m, i32 %evl) ret i32 %r } @@ -881,24 +871,14 @@ define signext i32 @vpreduce_smax_nxv1i32(i32 signext %s, %v, declare i32 @llvm.vp.reduce.umin.nxv1i32(i32, , , i32) define signext i32 @vpreduce_umin_nxv1i32(i32 signext %s, %v, %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umin_nxv1i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v9, a0 -; RV32-NEXT: vsetvli zero, a1, e32, mf2, ta, ma -; RV32-NEXT: vredminu.vs v9, v8, v9, v0.t -; RV32-NEXT: vmv.x.s a0, v9 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umin_nxv1i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v9, a0 -; RV64-NEXT: vsetvli zero, a1, e32, mf2, ta, ma -; RV64-NEXT: vredminu.vs v9, v8, v9, v0.t -; RV64-NEXT: vmv.x.s a0, v9 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umin_nxv1i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v9, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, mf2, ta, ma +; CHECK-NEXT: vredminu.vs v9, v8, v9, v0.t +; CHECK-NEXT: vmv.x.s a0, v9 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umin.nxv1i32(i32 %s, %v, %m, i32 %evl) ret i32 %r } @@ -981,24 +961,14 @@ define signext i32 @vpreduce_add_nxv2i32(i32 signext %s, %v, declare i32 @llvm.vp.reduce.umax.nxv2i32(i32, , , i32) define signext i32 @vpreduce_umax_nxv2i32(i32 signext %s, %v, %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umax_nxv2i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v9, a0 -; RV32-NEXT: vsetvli zero, a1, e32, m1, ta, ma -; RV32-NEXT: vredmaxu.vs v9, v8, v9, v0.t -; RV32-NEXT: vmv.x.s a0, v9 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umax_nxv2i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v9, a0 -; RV64-NEXT: vsetvli zero, a1, e32, m1, ta, ma -; RV64-NEXT: vredmaxu.vs v9, v8, v9, v0.t -; RV64-NEXT: vmv.x.s a0, v9 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umax_nxv2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v9, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma +; CHECK-NEXT: vredmaxu.vs v9, v8, v9, v0.t +; CHECK-NEXT: vmv.x.s a0, v9 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umax.nxv2i32(i32 %s, %v, %m, i32 %evl) ret i32 %r } @@ -1021,24 +991,14 @@ define signext i32 @vpreduce_smax_nxv2i32(i32 signext %s, %v, declare i32 @llvm.vp.reduce.umin.nxv2i32(i32, , , i32) define signext i32 @vpreduce_umin_nxv2i32(i32 signext %s, %v, %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umin_nxv2i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v9, a0 -; RV32-NEXT: vsetvli zero, a1, e32, m1, ta, ma -; RV32-NEXT: vredminu.vs v9, v8, v9, v0.t -; RV32-NEXT: vmv.x.s a0, v9 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umin_nxv2i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v9, a0 -; RV64-NEXT: vsetvli zero, a1, e32, m1, ta, ma -; RV64-NEXT: vredminu.vs v9, v8, v9, v0.t -; RV64-NEXT: vmv.x.s a0, v9 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umin_nxv2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v9, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma +; CHECK-NEXT: vredminu.vs v9, v8, v9, v0.t +; CHECK-NEXT: vmv.x.s a0, v9 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umin.nxv2i32(i32 %s, %v, %m, i32 %evl) ret i32 %r } @@ -1121,24 +1081,14 @@ define signext i32 @vpreduce_add_nxv4i32(i32 signext %s, %v, declare i32 @llvm.vp.reduce.umax.nxv4i32(i32, , , i32) define signext i32 @vpreduce_umax_nxv4i32(i32 signext %s, %v, %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umax_nxv4i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v10, a0 -; RV32-NEXT: vsetvli zero, a1, e32, m2, ta, ma -; RV32-NEXT: vredmaxu.vs v10, v8, v10, v0.t -; RV32-NEXT: vmv.x.s a0, v10 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umax_nxv4i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v10, a0 -; RV64-NEXT: vsetvli zero, a1, e32, m2, ta, ma -; RV64-NEXT: vredmaxu.vs v10, v8, v10, v0.t -; RV64-NEXT: vmv.x.s a0, v10 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umax_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v10, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; CHECK-NEXT: vredmaxu.vs v10, v8, v10, v0.t +; CHECK-NEXT: vmv.x.s a0, v10 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umax.nxv4i32(i32 %s, %v, %m, i32 %evl) ret i32 %r } @@ -1146,56 +1096,30 @@ define signext i32 @vpreduce_umax_nxv4i32(i32 signext %s, %v, declare i32 @llvm.vp.reduce.umax.nxv32i32(i32, , , i32) define signext i32 @vpreduce_umax_nxv32i32(i32 signext %s, %v, %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umax_nxv32i32: -; RV32: # %bb.0: -; RV32-NEXT: csrr a3, vlenb -; RV32-NEXT: srli a2, a3, 2 -; RV32-NEXT: vsetvli a4, zero, e8, mf2, ta, ma -; RV32-NEXT: vslidedown.vx v24, v0, a2 -; RV32-NEXT: slli a3, a3, 1 -; RV32-NEXT: sub a2, a1, a3 -; RV32-NEXT: sltu a4, a1, a2 -; RV32-NEXT: addi a4, a4, -1 -; RV32-NEXT: and a2, a4, a2 -; RV32-NEXT: bltu a1, a3, .LBB67_2 -; RV32-NEXT: # %bb.1: -; RV32-NEXT: mv a1, a3 -; RV32-NEXT: .LBB67_2: -; RV32-NEXT: vsetvli zero, zero, e32, m2, ta, ma -; RV32-NEXT: vmv.s.x v25, a0 -; RV32-NEXT: vsetvli zero, a1, e32, m8, ta, ma -; RV32-NEXT: vredmaxu.vs v25, v8, v25, v0.t -; RV32-NEXT: vsetvli zero, a2, e32, m8, ta, ma -; RV32-NEXT: vmv1r.v v0, v24 -; RV32-NEXT: vredmaxu.vs v25, v16, v25, v0.t -; RV32-NEXT: vmv.x.s a0, v25 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umax_nxv32i32: -; RV64: # %bb.0: -; RV64-NEXT: csrr a3, vlenb -; RV64-NEXT: srli a2, a3, 2 -; RV64-NEXT: vsetvli a4, zero, e8, mf2, ta, ma -; RV64-NEXT: vslidedown.vx v24, v0, a2 -; RV64-NEXT: andi a2, a0, -1 -; RV64-NEXT: slli a3, a3, 1 -; RV64-NEXT: sub a0, a1, a3 -; RV64-NEXT: sltu a4, a1, a0 -; RV64-NEXT: addi a4, a4, -1 -; RV64-NEXT: and a0, a4, a0 -; RV64-NEXT: bltu a1, a3, .LBB67_2 -; RV64-NEXT: # %bb.1: -; RV64-NEXT: mv a1, a3 -; RV64-NEXT: .LBB67_2: -; RV64-NEXT: vsetvli zero, zero, e32, m2, ta, ma -; RV64-NEXT: vmv.s.x v25, a2 -; RV64-NEXT: vsetvli zero, a1, e32, m8, ta, ma -; RV64-NEXT: vredmaxu.vs v25, v8, v25, v0.t -; RV64-NEXT: vsetvli zero, a0, e32, m8, ta, ma -; RV64-NEXT: vmv1r.v v0, v24 -; RV64-NEXT: vredmaxu.vs v25, v16, v25, v0.t -; RV64-NEXT: vmv.x.s a0, v25 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umax_nxv32i32: +; CHECK: # %bb.0: +; CHECK-NEXT: csrr a3, vlenb +; CHECK-NEXT: srli a2, a3, 2 +; CHECK-NEXT: vsetvli a4, zero, e8, mf2, ta, ma +; CHECK-NEXT: vslidedown.vx v24, v0, a2 +; CHECK-NEXT: slli a3, a3, 1 +; CHECK-NEXT: sub a2, a1, a3 +; CHECK-NEXT: sltu a4, a1, a2 +; CHECK-NEXT: addi a4, a4, -1 +; CHECK-NEXT: and a2, a4, a2 +; CHECK-NEXT: bltu a1, a3, .LBB67_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: mv a1, a3 +; CHECK-NEXT: .LBB67_2: +; CHECK-NEXT: vsetvli zero, zero, e32, m2, ta, ma +; CHECK-NEXT: vmv.s.x v25, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, m8, ta, ma +; CHECK-NEXT: vredmaxu.vs v25, v8, v25, v0.t +; CHECK-NEXT: vsetvli zero, a2, e32, m8, ta, ma +; CHECK-NEXT: vmv1r.v v0, v24 +; CHECK-NEXT: vredmaxu.vs v25, v16, v25, v0.t +; CHECK-NEXT: vmv.x.s a0, v25 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umax.nxv32i32(i32 %s, %v, %m, i32 %evl) ret i32 %r } @@ -1218,24 +1142,14 @@ define signext i32 @vpreduce_smax_nxv4i32(i32 signext %s, %v, declare i32 @llvm.vp.reduce.umin.nxv4i32(i32, , , i32) define signext i32 @vpreduce_umin_nxv4i32(i32 signext %s, %v, %m, i32 zeroext %evl) { -; RV32-LABEL: vpreduce_umin_nxv4i32: -; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV32-NEXT: vmv.s.x v10, a0 -; RV32-NEXT: vsetvli zero, a1, e32, m2, ta, ma -; RV32-NEXT: vredminu.vs v10, v8, v10, v0.t -; RV32-NEXT: vmv.x.s a0, v10 -; RV32-NEXT: ret -; -; RV64-LABEL: vpreduce_umin_nxv4i32: -; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 -; RV64-NEXT: vsetivli zero, 1, e32, m1, ta, ma -; RV64-NEXT: vmv.s.x v10, a0 -; RV64-NEXT: vsetvli zero, a1, e32, m2, ta, ma -; RV64-NEXT: vredminu.vs v10, v8, v10, v0.t -; RV64-NEXT: vmv.x.s a0, v10 -; RV64-NEXT: ret +; CHECK-LABEL: vpreduce_umin_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-NEXT: vmv.s.x v10, a0 +; CHECK-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; CHECK-NEXT: vredminu.vs v10, v8, v10, v0.t +; CHECK-NEXT: vmv.x.s a0, v10 +; CHECK-NEXT: ret %r = call i32 @llvm.vp.reduce.umin.nxv4i32(i32 %s, %v, %m, i32 %evl) ret i32 %r } diff --git a/llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll index 21ddf1a6e114..d70f619c3601 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll @@ -1484,7 +1484,6 @@ define @vwadd_vx_splat_zext( %va, i32 %b) { ; ; RV64-LABEL: vwadd_vx_splat_zext: ; RV64: # %bb.0: -; RV64-NEXT: andi a0, a0, -1 ; RV64-NEXT: vsetvli a1, zero, e32, m4, ta, ma ; RV64-NEXT: vwaddu.vx v16, v8, a0 ; RV64-NEXT: vmv8r.v v8, v16 -- GitLab From 011a65353b8b4dc018541f86356f2dfa0f124f1a Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Thu, 25 Apr 2024 14:24:17 +0800 Subject: [PATCH 057/733] [RISCV] Split out VSETVLIInfo AVL states to be more explicit (#89964) We currently use AVLIsReg to represent VLMAX as well as a dummy value for whenever the VL is ignored by vmv.x.s. This splits them out into separate states so that AVLIsReg is always a virtual register and should help with tracking the definition inside VSETVLIInfo directly in #89180. This is almost an NFC but it sets the kill flag for x0 in more places. --- llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 141 ++++++++++-------- .../RISCV/rvv/vsetvli-insert-crossbb.mir | 12 +- .../test/CodeGen/RISCV/rvv/vsetvli-insert.mir | 20 +-- 3 files changed, 98 insertions(+), 75 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp index ec1a9f4c135c..3d598dd6f708 100644 --- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp +++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp @@ -452,6 +452,8 @@ class VSETVLIInfo { Uninitialized, AVLIsReg, AVLIsImm, + AVLIsVLMAX, + AVLIsIgnored, Unknown, } State = Uninitialized; @@ -478,7 +480,7 @@ public: bool isUnknown() const { return State == Unknown; } void setAVLReg(Register Reg) { - assert(Reg.isVirtual() || Reg == RISCV::X0 || Reg == RISCV::NoRegister); + assert(Reg.isVirtual()); AVLReg = Reg; State = AVLIsReg; } @@ -488,8 +490,14 @@ public: State = AVLIsImm; } + void setAVLVLMAX() { State = AVLIsVLMAX; } + + void setAVLIgnored() { State = AVLIsIgnored; } + bool hasAVLImm() const { return State == AVLIsImm; } bool hasAVLReg() const { return State == AVLIsReg; } + bool hasAVLVLMAX() const { return State == AVLIsVLMAX; } + bool hasAVLIgnored() const { return State == AVLIsIgnored; } Register getAVLReg() const { assert(hasAVLReg()); return AVLReg; @@ -505,6 +513,10 @@ public: setUnknown(); else if (Info.hasAVLReg()) setAVLReg(Info.getAVLReg()); + else if (Info.hasAVLVLMAX()) + setAVLVLMAX(); + else if (Info.hasAVLIgnored()) + setAVLIgnored(); else { assert(Info.hasAVLImm()); setAVLImm(Info.getAVLImm()); @@ -520,13 +532,14 @@ public: if (hasAVLImm()) return getAVLImm() > 0; if (hasAVLReg()) { - if (getAVLReg() == RISCV::X0) - return true; - if (MachineInstr *MI = MRI.getVRegDef(getAVLReg()); - MI && isNonZeroLoadImmediate(*MI)) - return true; - return false; + MachineInstr *MI = MRI.getUniqueVRegDef(getAVLReg()); + assert(MI); + return isNonZeroLoadImmediate(*MI); } + if (hasAVLVLMAX()) + return true; + if (hasAVLIgnored()) + return false; return false; } @@ -544,6 +557,12 @@ public: if (hasAVLImm() && Other.hasAVLImm()) return getAVLImm() == Other.getAVLImm(); + if (hasAVLVLMAX()) + return Other.hasAVLVLMAX() && hasSameVLMAX(Other); + + if (hasAVLIgnored()) + return Other.hasAVLIgnored(); + return false; } @@ -717,6 +736,10 @@ public: OS << "AVLReg=" << (unsigned)AVLReg; if (hasAVLImm()) OS << "AVLImm=" << (unsigned)AVLImm; + if (hasAVLVLMAX()) + OS << "AVLVLMAX"; + if (hasAVLIgnored()) + OS << "AVLIgnored"; OS << ", " << "VLMul=" << (unsigned)VLMul << ", " << "SEW=" << (unsigned)SEW << ", " @@ -846,7 +869,10 @@ static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) { Register AVLReg = MI.getOperand(1).getReg(); assert((AVLReg != RISCV::X0 || MI.getOperand(0).getReg() != RISCV::X0) && "Can't handle X0, X0 vsetvli yet"); - NewInfo.setAVLReg(AVLReg); + if (AVLReg == RISCV::X0) + NewInfo.setAVLVLMAX(); + else + NewInfo.setAVLReg(AVLReg); } NewInfo.setVTYPE(MI.getOperand(2).getImm()); @@ -913,7 +939,7 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags, if (ST.getRealMinVLen() == ST.getRealMaxVLen() && VLMAX <= 31) InstrInfo.setAVLImm(VLMAX); else - InstrInfo.setAVLReg(RISCV::X0); + InstrInfo.setAVLVLMAX(); } else InstrInfo.setAVLImm(Imm); @@ -922,7 +948,10 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags, } } else { assert(isScalarExtractInstr(MI)); - InstrInfo.setAVLReg(RISCV::NoRegister); + // TODO: If we are more clever about x0,x0 insertion then we should be able + // to deduce that the VL is ignored based off of DemandedFields, and remove + // the AVLIsIgnored state. Then we can just use an arbitrary immediate AVL. + InstrInfo.setAVLIgnored(); } #ifndef NDEBUG if (std::optional EEW = getEEWForLoadStore(MI)) { @@ -935,14 +964,14 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags, // AVL operand with the AVL of the defining vsetvli. We avoid general // register AVLs to avoid extending live ranges without being sure we can // kill the original source reg entirely. - if (InstrInfo.hasAVLReg() && InstrInfo.getAVLReg().isVirtual()) { - MachineInstr *DefMI = MRI->getVRegDef(InstrInfo.getAVLReg()); - if (DefMI && isVectorConfigInstr(*DefMI)) { + if (InstrInfo.hasAVLReg()) { + MachineInstr *DefMI = MRI->getUniqueVRegDef(InstrInfo.getAVLReg()); + assert(DefMI); + if (isVectorConfigInstr(*DefMI)) { VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI); if (DefInstrInfo.hasSameVLMAX(InstrInfo) && - (DefInstrInfo.hasAVLImm() || DefInstrInfo.getAVLReg() == RISCV::X0)) { + (DefInstrInfo.hasAVLImm() || DefInstrInfo.hasAVLVLMAX())) InstrInfo.setAVL(DefInstrInfo); - } } } @@ -976,19 +1005,18 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB, // If our AVL is a virtual register, it might be defined by a VSET(I)VLI. If // it has the same VLMAX we want and the last VL/VTYPE we observed is the // same, we can use the X0, X0 form. - if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg() && - Info.getAVLReg().isVirtual()) { - if (MachineInstr *DefMI = MRI->getVRegDef(Info.getAVLReg())) { - if (isVectorConfigInstr(*DefMI)) { - VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); - if (DefInfo.hasSameAVL(PrevInfo) && DefInfo.hasSameVLMAX(PrevInfo)) { - BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0)) - .addReg(RISCV::X0, RegState::Define | RegState::Dead) - .addReg(RISCV::X0, RegState::Kill) - .addImm(Info.encodeVTYPE()) - .addReg(RISCV::VL, RegState::Implicit); - return; - } + if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg()) { + MachineInstr *DefMI = MRI->getUniqueVRegDef(Info.getAVLReg()); + assert(DefMI); + if (isVectorConfigInstr(*DefMI)) { + VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); + if (DefInfo.hasSameAVL(PrevInfo) && DefInfo.hasSameVLMAX(PrevInfo)) { + BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0)) + .addReg(RISCV::X0, RegState::Define | RegState::Dead) + .addReg(RISCV::X0, RegState::Kill) + .addImm(Info.encodeVTYPE()) + .addReg(RISCV::VL, RegState::Implicit); + return; } } } @@ -1002,8 +1030,7 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB, return; } - Register AVLReg = Info.getAVLReg(); - if (AVLReg == RISCV::NoRegister) { + if (Info.hasAVLIgnored()) { // We can only use x0, x0 if there's no chance of the vtype change causing // the previous vl to become invalid. if (PrevInfo.isValid() && !PrevInfo.isUnknown() && @@ -1023,20 +1050,19 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB, return; } - if (AVLReg.isVirtual()) - MRI->constrainRegClass(AVLReg, &RISCV::GPRNoX0RegClass); - - // Use X0 as the DestReg unless AVLReg is X0. We also need to change the - // opcode if the AVLReg is X0 as they have different register classes for - // the AVL operand. - Register DestReg = RISCV::X0; - unsigned Opcode = RISCV::PseudoVSETVLI; - if (AVLReg == RISCV::X0) { - DestReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); - Opcode = RISCV::PseudoVSETVLIX0; + if (Info.hasAVLVLMAX()) { + Register DestReg = MRI->createVirtualRegister(&RISCV::GPRRegClass); + BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0)) + .addReg(DestReg, RegState::Define | RegState::Dead) + .addReg(RISCV::X0, RegState::Kill) + .addImm(Info.encodeVTYPE()); + return; } - BuildMI(MBB, InsertPt, DL, TII->get(Opcode)) - .addReg(DestReg, RegState::Define | RegState::Dead) + + Register AVLReg = Info.getAVLReg(); + MRI->constrainRegClass(AVLReg, &RISCV::GPRNoX0RegClass); + BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLI)) + .addReg(RISCV::X0, RegState::Define | RegState::Dead) .addReg(AVLReg) .addImm(Info.encodeVTYPE()); } @@ -1098,14 +1124,13 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI, // it might be defined by a VSET(I)VLI. If it has the same VLMAX we need // and the last VL/VTYPE we observed is the same, we don't need a // VSETVLI here. - if (Require.hasAVLReg() && Require.getAVLReg().isVirtual() && - CurInfo.hasCompatibleVTYPE(Used, Require)) { - if (MachineInstr *DefMI = MRI->getVRegDef(Require.getAVLReg())) { - if (isVectorConfigInstr(*DefMI)) { - VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); - if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVLMAX(CurInfo)) - return false; - } + if (Require.hasAVLReg() && CurInfo.hasCompatibleVTYPE(Used, Require)) { + MachineInstr *DefMI = MRI->getUniqueVRegDef(Require.getAVLReg()); + assert(DefMI); + if (isVectorConfigInstr(*DefMI)) { + VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI); + if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVLMAX(CurInfo)) + return false; } } @@ -1290,12 +1315,11 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require, return true; Register AVLReg = Require.getAVLReg(); - if (!AVLReg.isVirtual()) - return true; // We need the AVL to be produce by a PHI node in this basic block. - MachineInstr *PHI = MRI->getVRegDef(AVLReg); - if (!PHI || PHI->getOpcode() != RISCV::PHI || PHI->getParent() != &MBB) + MachineInstr *PHI = MRI->getUniqueVRegDef(AVLReg); + assert(PHI); + if (PHI->getOpcode() != RISCV::PHI || PHI->getParent() != &MBB) return true; for (unsigned PHIOp = 1, NumOps = PHI->getNumOperands(); PHIOp != NumOps; @@ -1463,10 +1487,9 @@ void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) { // If the AVL value is a register (other than our VLMAX sentinel), // we need to prove the value is available at the point we're going // to insert the vsetvli at. - if (AvailableInfo.hasAVLReg() && RISCV::X0 != AvailableInfo.getAVLReg()) { - MachineInstr *AVLDefMI = MRI->getVRegDef(AvailableInfo.getAVLReg()); - if (!AVLDefMI) - return; + if (AvailableInfo.hasAVLReg()) { + MachineInstr *AVLDefMI = MRI->getUniqueVRegDef(AvailableInfo.getAVLReg()); + assert(AVLDefMI); // This is an inline dominance check which covers the case of // UnavailablePred being the preheader of a loop. if (AVLDefMI->getParent() != UnavailablePred) diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-crossbb.mir b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-crossbb.mir index fdcce72a01eb..596ea1c39fce 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-crossbb.mir +++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-crossbb.mir @@ -517,10 +517,10 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x10 ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr = IMPLICIT_DEF ; CHECK-NEXT: %pt:vr = IMPLICIT_DEF - ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 $x0, 223 /* e64, mf2, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 223 /* e64, mf2, ta, ma */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: [[PseudoVID_V_MF2_:%[0-9]+]]:vr = PseudoVID_V_MF2 %pt, -1, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: %pt2:vr = IMPLICIT_DEF - ; CHECK-NEXT: dead [[PseudoVSETVLIX0_1:%[0-9]+]]:gpr = PseudoVSETVLIX0 $x0, 215 /* e32, mf2, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoVSETVLIX0_1:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 215 /* e32, mf2, ta, ma */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: [[PseudoVMV_V_I_MF2_:%[0-9]+]]:vrnov0 = PseudoVMV_V_I_MF2 %pt2, 0, -1, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: @@ -609,7 +609,7 @@ body: | ; CHECK-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[PseudoReadVLENB]], 3 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 ; CHECK-NEXT: %pt:vr = IMPLICIT_DEF - ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: [[PseudoVID_V_M1_:%[0-9]+]]:vr = PseudoVID_V_M1 %pt, -1, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x0 ; CHECK-NEXT: {{ $}} @@ -681,7 +681,7 @@ body: | ; CHECK-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[PseudoReadVLENB]], 3 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 ; CHECK-NEXT: %pt:vr = IMPLICIT_DEF - ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: [[PseudoVID_V_M1_:%[0-9]+]]:vr = PseudoVID_V_M1 %pt, -1, 6 /* e64 */, 3 /* ta, ma */, implicit $vl, implicit $vtype ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x0 ; CHECK-NEXT: {{ $}} @@ -866,7 +866,7 @@ body: | ; CHECK-NEXT: %t3:vr = COPY $v2 ; CHECK-NEXT: %t4:vr = COPY $v3 ; CHECK-NEXT: %t5:vrnov0 = COPY $v1 - ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: %t6:vr = PseudoVMSEQ_VI_M1 %t1, 0, -1, 6 /* e64 */, implicit $vl, implicit $vtype ; CHECK-NEXT: PseudoBR %bb.1 ; CHECK-NEXT: {{ $}} @@ -949,7 +949,7 @@ body: | ; CHECK-NEXT: %vlenb:gpr = PseudoReadVLENB ; CHECK-NEXT: %inc:gpr = SRLI killed %vlenb, 3 ; CHECK-NEXT: %pt:vr = IMPLICIT_DEF - ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: [[PseudoVID_V_M1_:%[0-9]+]]:vr = PseudoVID_V_M1 %pt, -1, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x0 ; CHECK-NEXT: PseudoBR %bb.1 diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert.mir b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert.mir index 39f517a100f5..e567897aa868 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert.mir +++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert.mir @@ -324,7 +324,7 @@ body: | ; CHECK-NEXT: %pt:vr = IMPLICIT_DEF ; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 2, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: [[PseudoVLE64_V_M1_:%[0-9]+]]:vr = PseudoVLE64_V_M1 %pt, [[COPY]], 2, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype :: (load (s128) from %ir.x) - ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoVSETVLIX0_:%[0-9]+]]:gpr = PseudoVSETVLIX0 killed $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: [[PseudoVMV_V_I_M1_:%[0-9]+]]:vr = PseudoVMV_V_I_M1 $noreg, 0, -1, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF ; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 2, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype @@ -370,7 +370,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v9 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v8 - ; CHECK-NEXT: [[PseudoVSETVLI:%[0-9]+]]:gprnox0 = PseudoVSETVLI [[COPY]], 88 /* e64, m1, ta, mu */, implicit-def $vl, implicit-def $vtype + ; CHECK-NEXT: dead [[PseudoVSETVLI:%[0-9]+]]:gprnox0 = PseudoVSETVLI [[COPY]], 88 /* e64, m1, ta, mu */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: %pt:vr = IMPLICIT_DEF ; CHECK-NEXT: [[PseudoVADD_VV_M1_:%[0-9]+]]:vr = PseudoVADD_VV_M1 %pt, [[COPY2]], [[COPY1]], $noreg, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_]] @@ -445,9 +445,9 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %pt:vrm2 = IMPLICIT_DEF ; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 4, 217 /* e64, m2, ta, ma */, implicit-def $vl, implicit-def $vtype - ; CHECK-NEXT: [[PseudoVID_V_M2_:%[0-9]+]]:vrm2 = PseudoVID_V_M2 %pt, 4, 6 /* e64 */, 3 /* ta, ma */, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead [[PseudoVID_V_M2_:%[0-9]+]]:vrm2 = PseudoVID_V_M2 %pt, 4, 6 /* e64 */, 3 /* ta, ma */, implicit $vl, implicit $vtype ; CHECK-NEXT: dead $x0 = PseudoVSETVLIX0 killed $x0, 198 /* e8, mf4, ta, ma */, implicit-def $vl, implicit-def $vtype, implicit $vl - ; CHECK-NEXT: [[PseudoVMV_V_I_MF4_:%[0-9]+]]:vr = PseudoVMV_V_I_MF4 $noreg, 0, 4, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead [[PseudoVMV_V_I_MF4_:%[0-9]+]]:vr = PseudoVMV_V_I_MF4 $noreg, 0, 4, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: PseudoRET %pt:vrm2 = IMPLICIT_DEF %0:vrm2 = PseudoVID_V_M2 %pt, 4, 6, 3 @@ -467,14 +467,14 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %cond:gpr = COPY $x10 ; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 2, 215 /* e32, mf2, ta, ma */, implicit-def $vl, implicit-def $vtype - ; CHECK-NEXT: [[PseudoVMV_V_I_MF2_:%[0-9]+]]:vr = PseudoVMV_V_I_MF2 $noreg, 1, 2, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead [[PseudoVMV_V_I_MF2_:%[0-9]+]]:vr = PseudoVMV_V_I_MF2 $noreg, 1, 2, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: BEQ %cond, $x0, %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: dead $x0 = PseudoVSETVLIX0 killed $x0, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype, implicit $vl - ; CHECK-NEXT: [[PseudoVMV_V_I_M1_:%[0-9]+]]:vr = PseudoVMV_V_I_M1 $noreg, 1, 2, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead [[PseudoVMV_V_I_M1_:%[0-9]+]]:vr = PseudoVMV_V_I_M1 $noreg, 1, 2, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.4(0x40000000), %bb.3(0x40000000) @@ -488,8 +488,8 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.4: ; CHECK-NEXT: $x0 = PseudoVSETIVLI 2, 215 /* e32, mf2, ta, ma */, implicit-def $vl, implicit-def $vtype - ; CHECK-NEXT: [[PseudoVMV_X_S:%[0-9]+]]:gpr = PseudoVMV_X_S $noreg, 5 /* e32 */, implicit $vtype - ; CHECK-NEXT: [[PseudoVMV_V_I_MF2_1:%[0-9]+]]:vr = PseudoVMV_V_I_MF2 $noreg, 1, 2, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead [[PseudoVMV_X_S:%[0-9]+]]:gpr = PseudoVMV_X_S $noreg, 5 /* e32 */, implicit $vtype + ; CHECK-NEXT: dead [[PseudoVMV_V_I_MF2_1:%[0-9]+]]:vr = PseudoVMV_V_I_MF2 $noreg, 1, 2, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: PseudoRET bb.0: liveins: $x10 @@ -517,10 +517,10 @@ body: | ; CHECK: liveins: $x1 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 3, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $vtype + ; CHECK-NEXT: dead [[COPY:%[0-9]+]]:gpr = COPY $vtype ; CHECK-NEXT: $vl = COPY $x1 ; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 3, 216 /* e64, m1, ta, ma */, implicit-def $vl, implicit-def $vtype - ; CHECK-NEXT: [[PseudoVADD_VV_M1_:%[0-9]+]]:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 3, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype + ; CHECK-NEXT: dead [[PseudoVADD_VV_M1_:%[0-9]+]]:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 3, 6 /* e64 */, 0 /* tu, mu */, implicit $vl, implicit $vtype ; CHECK-NEXT: PseudoRET dead $x0 = PseudoVSETIVLI 3, 216, implicit-def $vl, implicit-def $vtype %1:gpr = COPY $vtype -- GitLab From 72b58146b14308c0c745111f082fc6354cefda22 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Thu, 25 Apr 2024 14:26:07 +0800 Subject: [PATCH 058/733] Revert "[NFC] [Serialization] Avoid using DeclID directly as much as possible" This reverts commit 42070a5c092ed420bf92ebf38229c594885e94c7. I forgot to touch lldb. --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/AST/Decl.h | 46 ++-- clang/include/clang/AST/DeclBase.h | 8 +- clang/include/clang/AST/DeclCXX.h | 59 +++-- clang/include/clang/AST/DeclFriend.h | 2 +- clang/include/clang/AST/DeclID.h | 140 ++++-------- clang/include/clang/AST/DeclObjC.h | 30 +-- clang/include/clang/AST/DeclOpenMP.h | 19 +- clang/include/clang/AST/DeclTemplate.h | 50 ++--- clang/include/clang/AST/ExternalASTSource.h | 6 +- clang/include/clang/Frontend/ASTUnit.h | 2 +- .../clang/Frontend/MultiplexConsumer.h | 2 +- .../clang/Sema/MultiplexExternalSemaSource.h | 2 +- .../include/clang/Serialization/ASTBitCodes.h | 27 ++- .../ASTDeserializationListener.h | 2 +- clang/include/clang/Serialization/ASTReader.h | 8 +- clang/include/clang/Serialization/ASTWriter.h | 28 ++- .../include/clang/Serialization/ModuleFile.h | 6 +- clang/lib/AST/ASTContext.cpp | 3 +- clang/lib/AST/Decl.cpp | 47 ++-- clang/lib/AST/DeclBase.cpp | 6 +- clang/lib/AST/DeclCXX.cpp | 67 +++--- clang/lib/AST/DeclFriend.cpp | 2 +- clang/lib/AST/DeclObjC.cpp | 29 ++- clang/lib/AST/DeclOpenMP.cpp | 20 +- clang/lib/AST/DeclTemplate.cpp | 48 ++-- clang/lib/AST/ExternalASTSource.cpp | 2 +- clang/lib/Frontend/ASTUnit.cpp | 8 +- clang/lib/Frontend/FrontendAction.cpp | 6 +- clang/lib/Frontend/MultiplexConsumer.cpp | 3 +- .../lib/Sema/MultiplexExternalSemaSource.cpp | 2 +- clang/lib/Serialization/ASTReader.cpp | 28 +-- clang/lib/Serialization/ASTReaderDecl.cpp | 211 ++++++++++-------- clang/lib/Serialization/ASTWriter.cpp | 77 +++---- clang/lib/Serialization/ASTWriterDecl.cpp | 22 +- 35 files changed, 479 insertions(+), 543 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 24388ad5dea5..ecec9bfcf300 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -455,7 +455,7 @@ class ASTContext : public RefCountedBase { /// initialization of another module). struct PerModuleInitializers { llvm::SmallVector Initializers; - llvm::SmallVector LazyInitializers; + llvm::SmallVector LazyInitializers; void resolve(ASTContext &Ctx); }; @@ -1059,7 +1059,7 @@ public: /// or an ImportDecl nominating another module that has initializers. void addModuleInitializer(Module *M, Decl *Init); - void addLazyModuleInitializers(Module *M, ArrayRef IDs); + void addLazyModuleInitializers(Module *M, ArrayRef IDs); /// Get the initializations to perform when importing a module, if any. ArrayRef getModuleInitializers(Module *M); diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index a53c27a99a8c..8b121896d66d 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -157,7 +157,7 @@ public: SourceLocation CommentLoc, PragmaMSCommentKind CommentKind, StringRef Arg); - static PragmaCommentDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, + static PragmaCommentDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned ArgSize); PragmaMSCommentKind getCommentKind() const { return CommentKind; } @@ -192,7 +192,7 @@ public: SourceLocation Loc, StringRef Name, StringRef Value); static PragmaDetectMismatchDecl * - CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize); + CreateDeserialized(ASTContext &C, DeclID ID, unsigned NameValueSize); StringRef getName() const { return getTrailingObjects(); } StringRef getValue() const { return getTrailingObjects() + ValueStart; } @@ -518,7 +518,7 @@ public: static LabelDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, SourceLocation GnuLabelL); - static LabelDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static LabelDecl *CreateDeserialized(ASTContext &C, DeclID ID); LabelStmt *getStmt() const { return TheStmt; } void setStmt(LabelStmt *T) { TheStmt = T; } @@ -581,7 +581,7 @@ public: IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested); - static NamespaceDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static NamespaceDecl *CreateDeserialized(ASTContext &C, DeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -1146,7 +1146,7 @@ public: const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S); - static VarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static VarDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -1728,7 +1728,7 @@ public: static ImplicitParamDecl *Create(ASTContext &C, QualType T, ImplicitParamKind ParamKind); - static ImplicitParamDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ImplicitParamDecl *CreateDeserialized(ASTContext &C, DeclID ID); ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType Type, @@ -1782,7 +1782,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg); - static ParmVarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ParmVarDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -2178,7 +2178,7 @@ public: bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause); - static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static FunctionDecl *CreateDeserialized(ASTContext &C, DeclID ID); DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); @@ -3136,7 +3136,7 @@ public: TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle); - static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static FieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Returns the index of this field within its record, /// as appropriate for passing to ASTRecordLayout::getFieldOffset. @@ -3311,7 +3311,7 @@ public: SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, const llvm::APSInt &V); - static EnumConstantDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static EnumConstantDecl *CreateDeserialized(ASTContext &C, DeclID ID); const Expr *getInitExpr() const { return (const Expr*) Init; } Expr *getInitExpr() { return (Expr*) Init; } @@ -3357,7 +3357,7 @@ public: QualType T, llvm::MutableArrayRef CH); - static IndirectFieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static IndirectFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); using chain_iterator = ArrayRef::const_iterator; @@ -3542,7 +3542,7 @@ public: static TypedefDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypedefDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static TypedefDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3567,7 +3567,7 @@ public: static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypeAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static TypeAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3977,7 +3977,7 @@ public: IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed); - static EnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static EnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Overrides to provide correct range when there's an enum-base specifier /// with forward declarations. @@ -4182,7 +4182,7 @@ public: static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr); - static RecordDecl *CreateDeserialized(const ASTContext &C, GlobalDeclID ID); + static RecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); RecordDecl *getPreviousDecl() { return cast_or_null( @@ -4433,7 +4433,7 @@ public: StringLiteral *Str, SourceLocation AsmLoc, SourceLocation RParenLoc); - static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceLocation getAsmLoc() const { return getLocation(); } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -4469,7 +4469,7 @@ class TopLevelStmtDecl : public Decl, public DeclContext { public: static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement); - static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; Stmt *getStmt() { return Statement; } @@ -4563,7 +4563,7 @@ protected: public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static BlockDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static BlockDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceLocation getCaretLocation() const { return getLocation(); } @@ -4717,7 +4717,7 @@ public: static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); - static CapturedDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, + static CapturedDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumParams); Stmt *getBody() const override; @@ -4851,7 +4851,7 @@ public: SourceLocation EndLoc); /// Create a new, deserialized module import declaration. - static ImportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, + static ImportDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumLocations); /// Retrieve the module that was imported by the import declaration. @@ -4892,7 +4892,7 @@ private: public: static ExportDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc); - static ExportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ExportDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceLocation getExportLoc() const { return getLocation(); } SourceLocation getRBraceLoc() const { return RBraceLoc; } @@ -4931,7 +4931,7 @@ class EmptyDecl : public Decl { public: static EmptyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static EmptyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static EmptyDecl *CreateDeserialized(ASTContext &C, DeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Empty; } @@ -4957,7 +4957,7 @@ public: bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); - static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static HLSLBufferDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(getLocStart(), RBraceLoc); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index e43e812cd945..474e51c1df6d 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -359,7 +359,7 @@ protected: /// \param Ctx The context in which we will allocate memory. /// \param ID The global ID of the deserialized declaration. /// \param Extra The amount of extra space to allocate after the object. - void *operator new(std::size_t Size, const ASTContext &Ctx, GlobalDeclID ID, + void *operator new(std::size_t Size, const ASTContext &Ctx, DeclID ID, std::size_t Extra = 0); /// Allocate memory for a non-deserialized declaration. @@ -777,10 +777,10 @@ public: /// Retrieve the global declaration ID associated with this /// declaration, which specifies where this Decl was loaded from. - GlobalDeclID getGlobalID() const { + DeclID getGlobalID() const { if (isFromASTFile()) - return (*((const GlobalDeclID *)this - 1)); - return GlobalDeclID(); + return *((const DeclID *)this - 1); + return 0; } /// Retrieve the global ID of the module that owns this particular diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index fb52ac804849..a7644d2a19d2 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -120,7 +120,7 @@ public: return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); } - static AccessSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static AccessSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -579,8 +579,7 @@ public: TypeSourceInfo *Info, SourceLocation Loc, unsigned DependencyKind, bool IsGeneric, LambdaCaptureDefault CaptureDefault); - static CXXRecordDecl *CreateDeserialized(const ASTContext &C, - GlobalDeclID ID); + static CXXRecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); bool isDynamicClass() const { return data().Polymorphic || data().NumVBases != 0; @@ -1981,8 +1980,7 @@ public: CXXConstructorDecl *Ctor = nullptr, DeductionCandidate Kind = DeductionCandidate::Normal); - static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, DeclID ID); ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; } const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; } @@ -2037,8 +2035,7 @@ public: static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc); - static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2081,7 +2078,7 @@ public: ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static CXXMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); bool isStatic() const; bool isInstance() const { return !isStatic(); } @@ -2582,7 +2579,7 @@ public: friend class ASTDeclWriter; friend TrailingObjects; - static CXXConstructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, DeclID ID, uint64_t AllocKind); static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, @@ -2825,7 +2822,7 @@ public: bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause = nullptr); - static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static CXXDestructorDecl *CreateDeserialized(ASTContext & C, DeclID ID); void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg); @@ -2884,7 +2881,7 @@ public: bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXConversionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static CXXConversionDecl *CreateDeserialized(ASTContext &C, DeclID ID); ExplicitSpecifier getExplicitSpecifier() { return getCanonicalDecl()->ExplicitSpec; @@ -2951,7 +2948,7 @@ public: SourceLocation ExternLoc, SourceLocation LangLoc, LinkageSpecLanguageIDs Lang, bool HasBraces); - static LinkageSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static LinkageSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Return the language specified by this linkage specification. LinkageSpecLanguageIDs getLanguage() const { @@ -3099,7 +3096,7 @@ public: SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor); - static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(UsingLoc, getLocation()); @@ -3160,7 +3157,7 @@ public: SourceLocation IdentLoc, NamedDecl *Namespace); - static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3257,7 +3254,7 @@ public: LifetimeExtendedTemporaryDecl(Temp, EDec, Mangling); } static LifetimeExtendedTemporaryDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) LifetimeExtendedTemporaryDecl(EmptyShell{}); } @@ -3360,7 +3357,7 @@ public: UsingShadowDecl(UsingShadow, C, DC, Loc, Name, Introducer, Target); } - static UsingShadowDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static UsingShadowDecl *CreateDeserialized(ASTContext &C, DeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3569,7 +3566,7 @@ public: const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword); - static UsingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static UsingDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3648,7 +3645,7 @@ public: UsingDecl *Using, NamedDecl *Target, bool IsVirtual); static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + DeclID ID); /// Override the UsingShadowDecl's getIntroducer, returning the UsingDecl that /// introduced this. @@ -3760,7 +3757,7 @@ public: SourceLocation UsingL, SourceLocation EnumL, SourceLocation NameL, TypeSourceInfo *EnumType); - static UsingEnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static UsingEnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3833,7 +3830,7 @@ public: NamedDecl *InstantiatedFrom, ArrayRef UsingDecls); - static UsingPackDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, + static UsingPackDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumExpansions); SourceRange getSourceRange() const override LLVM_READONLY { @@ -3926,8 +3923,8 @@ public: NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc); - static UnresolvedUsingValueDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static UnresolvedUsingValueDecl * + CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -4017,8 +4014,8 @@ public: SourceLocation TargetNameLoc, DeclarationName TargetName, SourceLocation EllipsisLoc); - static UnresolvedUsingTypenameDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static UnresolvedUsingTypenameDecl * + CreateDeserialized(ASTContext &C, DeclID ID); /// Retrieves the canonical declaration of this declaration. UnresolvedUsingTypenameDecl *getCanonicalDecl() override { @@ -4048,7 +4045,7 @@ public: SourceLocation Loc, DeclarationName Name); static UnresolvedUsingIfExistsDecl *CreateDeserialized(ASTContext &Ctx, - GlobalDeclID ID); + DeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingIfExists; } @@ -4076,7 +4073,7 @@ public: SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *Message, SourceLocation RParenLoc, bool Failed); - static StaticAssertDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static StaticAssertDecl *CreateDeserialized(ASTContext &C, DeclID ID); Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); } const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); } @@ -4123,7 +4120,7 @@ public: static BindingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id); - static BindingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static BindingDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Get the expression to which this declaration is bound. This may be null /// in two different cases: while parsing the initializer for the @@ -4192,7 +4189,7 @@ public: QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef Bindings); - static DecompositionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, + static DecompositionDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumBindings); ArrayRef bindings() const { @@ -4249,7 +4246,7 @@ public: SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL, IdentifierInfo *Getter, IdentifierInfo *Setter); - static MSPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static MSPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); static bool classof(const Decl *D) { return D->getKind() == MSProperty; } @@ -4303,7 +4300,7 @@ private: MSGuidDecl(DeclContext *DC, QualType T, Parts P); static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P); - static MSGuidDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static MSGuidDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Only ASTContext::getMSGuidDecl and deserialization create these. friend class ASTContext; @@ -4356,7 +4353,7 @@ class UnnamedGlobalConstantDecl : public ValueDecl, static UnnamedGlobalConstantDecl *Create(const ASTContext &C, QualType T, const APValue &APVal); static UnnamedGlobalConstantDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + DeclID ID); // Only ASTContext::getUnnamedGlobalConstantDecl and deserialization create // these. diff --git a/clang/include/clang/AST/DeclFriend.h b/clang/include/clang/AST/DeclFriend.h index 9789282f351a..b56627a5337d 100644 --- a/clang/include/clang/AST/DeclFriend.h +++ b/clang/include/clang/AST/DeclFriend.h @@ -112,7 +112,7 @@ public: Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, ArrayRef FriendTypeTPLists = std::nullopt); - static FriendDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, + static FriendDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned FriendTypeNumTPLists); /// If this friend declaration names an (untemplated but possibly diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h index 614ba06b6386..e2c6dd65e86b 100644 --- a/clang/include/clang/AST/DeclID.h +++ b/clang/include/clang/AST/DeclID.h @@ -16,7 +16,6 @@ #ifndef LLVM_CLANG_AST_DECLID_H #define LLVM_CLANG_AST_DECLID_H -#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/iterator.h" namespace clang { @@ -89,139 +88,90 @@ enum PredefinedDeclIDs { /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. const unsigned int NUM_PREDEF_DECL_IDS = 18; -/// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means -/// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the -/// LocalDeclID to the ModuleFile been writting is equal to the GlobalDeclID. -/// Outside the serializer, all the DeclID been used should be GlobalDeclID. -/// We can translate a LocalDeclID to the GlobalDeclID by -/// `ASTReader::getGlobalDeclID()`. +/// An ID number that refers to a declaration in an AST file. +/// +/// The ID numbers of declarations are consecutive (in order of +/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. +/// At the start of a chain of precompiled headers, declaration ID 1 is +/// used for the translation unit declaration. +using DeclID = uint32_t; -class DeclIDBase { +class LocalDeclID { public: - /// An ID number that refers to a declaration in an AST file. - /// - /// The ID numbers of declarations are consecutive (in order of - /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. - /// At the start of a chain of precompiled headers, declaration ID 1 is - /// used for the translation unit declaration. - /// - /// DeclID should only be used directly in serialization. All other users - /// should use LocalDeclID or GlobalDeclID. - using DeclID = uint32_t; - -protected: - DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {} - explicit DeclIDBase(DeclID ID) : ID(ID) {} + explicit LocalDeclID(DeclID ID) : ID(ID) {} -public: DeclID get() const { return ID; } - explicit operator DeclID() const { return ID; } +private: + DeclID ID; +}; - explicit operator PredefinedDeclIDs() const { return (PredefinedDeclIDs)ID; } +/// Wrapper class for DeclID. This is helpful to not mix the use of LocalDeclID +/// and GlobalDeclID to improve the type safety. +class GlobalDeclID { +public: + GlobalDeclID() : ID(PREDEF_DECL_NULL_ID) {} + explicit GlobalDeclID(DeclID ID) : ID(ID) {} - bool isValid() const { return ID != PREDEF_DECL_NULL_ID; } + DeclID get() const { return ID; } - bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; } + explicit operator DeclID() const { return ID; } - friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) { + friend bool operator==(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { return LHS.ID == RHS.ID; } - friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) { + friend bool operator!=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { return LHS.ID != RHS.ID; } - // We may sort the decl ID. - friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) { + // We may sort the global decl ID. + friend bool operator<(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { return LHS.ID < RHS.ID; } - friend bool operator>(const DeclIDBase &LHS, const DeclIDBase &RHS) { + friend bool operator>(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { return LHS.ID > RHS.ID; } - friend bool operator<=(const DeclIDBase &LHS, const DeclIDBase &RHS) { + friend bool operator<=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { return LHS.ID <= RHS.ID; } - friend bool operator>=(const DeclIDBase &LHS, const DeclIDBase &RHS) { + friend bool operator>=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { return LHS.ID >= RHS.ID; } -protected: +private: DeclID ID; }; -class LocalDeclID : public DeclIDBase { - using Base = DeclIDBase; - +/// A helper iterator adaptor to convert the iterators to `SmallVector` +/// to the iterators to `SmallVector`. +class GlobalDeclIDIterator + : public llvm::iterator_adaptor_base { public: - LocalDeclID() : Base() {} - LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {} - explicit LocalDeclID(DeclID ID) : Base(ID) {} - - LocalDeclID &operator++() { - ++ID; - return *this; - } - - LocalDeclID operator++(int) { - LocalDeclID Ret = *this; - ++(*this); - return Ret; - } -}; + GlobalDeclIDIterator() : iterator_adaptor_base(nullptr) {} -class GlobalDeclID : public DeclIDBase { - using Base = DeclIDBase; + GlobalDeclIDIterator(const DeclID *ID) : iterator_adaptor_base(ID) {} -public: - GlobalDeclID() : Base() {} - explicit GlobalDeclID(DeclID ID) : Base(ID) {} + value_type operator*() const { return GlobalDeclID(*I); } - // For DeclIDIterator to be able to convert a GlobalDeclID - // to a LocalDeclID. - explicit operator LocalDeclID() const { return LocalDeclID(this->ID); } + bool operator==(const GlobalDeclIDIterator &RHS) const { return I == RHS.I; } }; /// A helper iterator adaptor to convert the iterators to -/// `SmallVector` to the iterators to `SmallVector`. -template +/// `SmallVector` to the iterators to `SmallVector`. class DeclIDIterator - : public llvm::iterator_adaptor_base, - const FromTy *, - std::forward_iterator_tag, ToTy> { + : public llvm::iterator_adaptor_base { public: - DeclIDIterator() : DeclIDIterator::iterator_adaptor_base(nullptr) {} + DeclIDIterator() : iterator_adaptor_base(nullptr) {} - DeclIDIterator(const FromTy *ID) - : DeclIDIterator::iterator_adaptor_base(ID) {} + DeclIDIterator(const GlobalDeclID *ID) : iterator_adaptor_base(ID) {} - ToTy operator*() const { return ToTy(*this->I); } + value_type operator*() const { return DeclID(*I); } - bool operator==(const DeclIDIterator &RHS) const { return this->I == RHS.I; } + bool operator==(const DeclIDIterator &RHS) const { return I == RHS.I; } }; } // namespace clang -namespace llvm { -template <> struct DenseMapInfo { - using GlobalDeclID = clang::GlobalDeclID; - using DeclID = GlobalDeclID::DeclID; - - static GlobalDeclID getEmptyKey() { - return GlobalDeclID(DenseMapInfo::getEmptyKey()); - } - - static GlobalDeclID getTombstoneKey() { - return GlobalDeclID(DenseMapInfo::getTombstoneKey()); - } - - static unsigned getHashValue(const GlobalDeclID &Key) { - return DenseMapInfo::getHashValue(Key.get()); - } - - static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) { - return L == R; - } -}; - -} // namespace llvm - #endif diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index d2cc61ca19f8..7780afa6f1cf 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -236,7 +236,7 @@ public: ObjCImplementationControl impControl = ObjCImplementationControl::None, bool HasRelatedResultType = false); - static ObjCMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ObjCMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); ObjCMethodDecl *getCanonicalDecl() override; const ObjCMethodDecl *getCanonicalDecl() const { @@ -614,8 +614,7 @@ public: IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo); - static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, - GlobalDeclID ID); + static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -790,7 +789,7 @@ public: TypeSourceInfo *TSI, PropertyControl propControl = None); - static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } @@ -1280,8 +1279,7 @@ public: ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc = SourceLocation(), bool isInternal = false); - static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, - GlobalDeclID ID); + static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, DeclID ID); /// Retrieve the type parameters of this class. /// @@ -1971,7 +1969,7 @@ public: TypeSourceInfo *TInfo, AccessControl ac, Expr *BW = nullptr, bool synthesized = false); - static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ObjCIvarDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Return the class interface that this ivar is logically contained /// in; this is either the interface where the ivar was declared, or the @@ -2041,8 +2039,7 @@ public: SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW); - static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2145,7 +2142,7 @@ public: SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl); - static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, DeclID ID); const ObjCProtocolList &getReferencedProtocols() const { assert(hasDefinition() && "No definition available!"); @@ -2364,7 +2361,7 @@ public: ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc = SourceLocation(), SourceLocation IvarRBraceLoc = SourceLocation()); - static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, DeclID ID); ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -2561,8 +2558,7 @@ public: Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc); - static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); ObjCCategoryDecl *getCategoryDecl() const; @@ -2644,8 +2640,7 @@ public: SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()); - static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// init_iterator - Iterates through the ivar initializer list. using init_iterator = CXXCtorInitializer **; @@ -2785,7 +2780,7 @@ public: ObjCInterfaceDecl* aliasedClass); static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + DeclID ID); const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } @@ -2856,8 +2851,7 @@ public: ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc); - static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h index cad7a619a635..c7ede7f2157f 100644 --- a/clang/include/clang/AST/DeclOpenMP.h +++ b/clang/include/clang/AST/DeclOpenMP.h @@ -59,9 +59,9 @@ protected: } template - static T *createEmptyDirective(const ASTContext &C, GlobalDeclID ID, + static T *createEmptyDirective(const ASTContext &C, unsigned ID, unsigned NumClauses, unsigned NumChildren, - Params &&...P) { + Params &&... P) { auto *Inst = new (C, ID, size(NumClauses, NumChildren)) T(nullptr, std::forward(P)...); Inst->Data = OMPChildren::CreateEmpty( @@ -133,7 +133,7 @@ public: SourceLocation L, ArrayRef VL); static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID, unsigned N); + DeclID ID, unsigned N); typedef MutableArrayRef::iterator varlist_iterator; typedef ArrayRef::iterator varlist_const_iterator; @@ -214,7 +214,7 @@ public: QualType T, OMPDeclareReductionDecl *PrevDeclInScope); /// Create deserialized declare reduction node. static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + DeclID ID); /// Get combiner expression of the declare reduction construct. Expr *getCombiner() { return Combiner; } @@ -318,8 +318,8 @@ public: ArrayRef Clauses, OMPDeclareMapperDecl *PrevDeclInScope); /// Creates deserialized declare mapper node. - static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID, unsigned N); + static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, DeclID ID, + unsigned N); using clauselist_iterator = MutableArrayRef::iterator; using clauselist_const_iterator = ArrayRef::iterator; @@ -397,8 +397,7 @@ public: IdentifierInfo *Id, QualType T, SourceLocation StartLoc); - static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, DeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -428,7 +427,7 @@ public: static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef CL); /// Create deserialized requires node. - static OMPRequiresDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, + static OMPRequiresDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; @@ -496,7 +495,7 @@ public: static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef VL, ArrayRef CL); - static OMPAllocateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, + static OMPAllocateDecl *CreateDeserialized(ASTContext &C, DeclID ID, unsigned NVars, unsigned NClauses); typedef MutableArrayRef::iterator varlist_iterator; diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 3ee03eebdb8c..0c95459a6ab1 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -797,7 +797,7 @@ protected: /// /// The first value in the array is the number of specializations/partial /// specializations that follow. - GlobalDeclID *LazySpecializations = nullptr; + DeclID *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -1087,8 +1087,7 @@ public: NamedDecl *Decl); /// Create an empty function template node. - static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1205,9 +1204,9 @@ public: bool Typename, bool ParameterPack, bool HasTypeConstraint = false, std::optional NumExpanded = std::nullopt); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - GlobalDeclID ID); + DeclID ID); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - GlobalDeclID ID, + DeclID ID, bool HasTypeConstraint); /// Whether this template type parameter was declared with @@ -1414,10 +1413,11 @@ public: QualType T, TypeSourceInfo *TInfo, ArrayRef ExpandedTypes, ArrayRef ExpandedTInfos); - static NonTypeTemplateParmDecl * - CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID, + DeclID ID, + bool HasTypeConstraint); + static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, + DeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint); @@ -1632,9 +1632,10 @@ public: ArrayRef Expansions); static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); - static TemplateTemplateParmDecl * - CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions); + DeclID ID); + static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, + DeclID ID, + unsigned NumExpansions); using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; @@ -1856,8 +1857,8 @@ public: ClassTemplateDecl *SpecializedTemplate, ArrayRef Args, ClassTemplateSpecializationDecl *PrevDecl); - static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static ClassTemplateSpecializationDecl * + CreateDeserialized(ASTContext &C, DeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2109,7 +2110,7 @@ public: ClassTemplatePartialSpecializationDecl *PrevDecl); static ClassTemplatePartialSpecializationDecl * - CreateDeserialized(ASTContext &C, GlobalDeclID ID); + CreateDeserialized(ASTContext &C, DeclID ID); ClassTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -2305,7 +2306,7 @@ public: NamedDecl *Decl); /// Create an empty class template node. - static ClassTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ClassTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -2471,7 +2472,7 @@ public: MutableArrayRef Params, FriendUnion Friend, SourceLocation FriendLoc); - static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static FriendTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// If this friend declaration names a templated type (or /// a dependent member type of a templated type), return that @@ -2572,8 +2573,7 @@ public: NamedDecl *Decl); /// Create an empty alias template node. - static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2670,7 +2670,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args); static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + DeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2900,8 +2900,8 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args, const TemplateArgumentListInfo &ArgInfos); - static VarTemplatePartialSpecializationDecl * - CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, + DeclID ID); VarTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -3078,7 +3078,7 @@ public: VarDecl *Decl); /// Create an empty variable template node. - static VarTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static VarTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -3183,7 +3183,7 @@ public: SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr); - static ConceptDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); + static ConceptDecl *CreateDeserialized(ASTContext &C, DeclID ID); Expr *getConstraintExpr() const { return ConstraintExpr; @@ -3232,7 +3232,7 @@ public: Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef ConvertedArgs); static ImplicitConceptSpecializationDecl * - CreateDeserialized(const ASTContext &C, GlobalDeclID ID, + CreateDeserialized(const ASTContext &C, DeclID ID, unsigned NumTemplateArgs); ArrayRef getTemplateArguments() const { @@ -3275,7 +3275,7 @@ private: static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T, const APValue &V); static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C, - GlobalDeclID ID); + DeclID ID); /// Only ASTContext::getTemplateParamObjectDecl and deserialization /// create these. diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index 385c32edbae0..d0ee8ce6365a 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -99,7 +99,7 @@ public: /// passes back decl sets as VisibleDeclaration objects. /// /// The default implementation of this method is a no-op. - virtual Decl *GetExternalDecl(GlobalDeclID ID); + virtual Decl *GetExternalDecl(DeclID ID); /// Resolve a selector ID into a selector. /// @@ -375,7 +375,7 @@ public: if (isOffset()) { assert(Source && "Cannot deserialize a lazy pointer without an AST source"); - Ptr = reinterpret_cast((Source->*Get)(OffsT(Ptr >> 1))); + Ptr = reinterpret_cast((Source->*Get)(Ptr >> 1)); } return reinterpret_cast(Ptr); } @@ -579,7 +579,7 @@ using LazyDeclStmtPtr = /// A lazy pointer to a declaration. using LazyDeclPtr = - LazyOffsetPtr; + LazyOffsetPtr; /// A lazy pointer to a set of CXXCtorInitializers. using LazyCXXCtorInitializersPtr = diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 080844893c13..163e87cd3df3 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -241,7 +241,7 @@ private: /// A list of the serialization ID numbers for each of the top-level /// declarations parsed within the precompiled preamble. - std::vector TopLevelDeclsInPreamble; + std::vector TopLevelDeclsInPreamble; /// Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults : 1; diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h b/clang/include/clang/Frontend/MultiplexConsumer.h index f29c8e92fded..6a82c0dd8cec 100644 --- a/clang/include/clang/Frontend/MultiplexConsumer.h +++ b/clang/include/clang/Frontend/MultiplexConsumer.h @@ -35,7 +35,7 @@ public: void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; void MacroRead(serialization::MacroID ID, MacroInfo *MI) override; void TypeRead(serialization::TypeIdx Idx, QualType T) override; - void DeclRead(GlobalDeclID ID, const Decl *D) override; + void DeclRead(DeclID ID, const Decl *D) override; void SelectorRead(serialization::SelectorID iD, Selector Sel) override; void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD) override; diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index 238fb398b7d1..da3204863a41 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -65,7 +65,7 @@ public: /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. - Decl *GetExternalDecl(GlobalDeclID ID) override; + Decl *GetExternalDecl(DeclID ID) override; /// Complete the redeclaration chain if it's been extended since the /// previous generation of the AST source. diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 186c3b722ced..42e09a2bf634 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -60,10 +60,6 @@ const unsigned VERSION_MINOR = 1; /// and start at 1. 0 is reserved for NULL. using IdentifierID = uint32_t; -/// An ID number that refers to a declaration in an AST file. See the comments -/// in DeclIDBase for details. -using DeclID = DeclIDBase::DeclID; - /// An ID number that refers to a type in an AST file. /// /// The ID of a type is partitioned into two parts: the lower @@ -1983,7 +1979,7 @@ enum CleanupObjectKind { COK_Block, COK_CompoundLiteral }; /// Describes the categories of an Objective-C class. struct ObjCCategoriesInfo { // The ID of the definition - LocalDeclID DefinitionID; + DeclID DefinitionID; // Offset into the array of category lists. unsigned Offset; @@ -2082,6 +2078,27 @@ template <> struct DenseMapInfo { } }; +template <> struct DenseMapInfo { + using DeclID = clang::DeclID; + using GlobalDeclID = clang::GlobalDeclID; + + static GlobalDeclID getEmptyKey() { + return GlobalDeclID(DenseMapInfo::getEmptyKey()); + } + + static GlobalDeclID getTombstoneKey() { + return GlobalDeclID(DenseMapInfo::getTombstoneKey()); + } + + static unsigned getHashValue(const GlobalDeclID &Key) { + return DenseMapInfo::getHashValue(Key.get()); + } + + static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) { + return L == R; + } +}; + } // namespace llvm #endif // LLVM_CLANG_SERIALIZATION_ASTBITCODES_H diff --git a/clang/include/clang/Serialization/ASTDeserializationListener.h b/clang/include/clang/Serialization/ASTDeserializationListener.h index 3ab7f1a91843..bb039558f7f7 100644 --- a/clang/include/clang/Serialization/ASTDeserializationListener.h +++ b/clang/include/clang/Serialization/ASTDeserializationListener.h @@ -44,7 +44,7 @@ public: /// unqualified. virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { } /// A decl was deserialized from the AST file. - virtual void DeclRead(GlobalDeclID ID, const Decl *D) {} + virtual void DeclRead(DeclID ID, const Decl *D) {} /// A selector was read from the AST file. virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {} /// A macro definition was read from the AST file. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 64f1ebc117b3..65e2bcb990c3 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -603,8 +603,7 @@ private: /// Decl::Kind, DeclID pairs. using unalighed_decl_id_t = llvm::support::detail::packed_endian_specific_integral< - serialization::DeclID, llvm::endianness::native, - llvm::support::unaligned>; + DeclID, llvm::endianness::native, llvm::support::unaligned>; using LexicalContents = ArrayRef; /// Map from a DeclContext to its lexical contents. @@ -1919,7 +1918,7 @@ public: /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. Decl *GetDecl(GlobalDeclID ID); - Decl *GetExternalDecl(GlobalDeclID ID) override; + Decl *GetExternalDecl(DeclID ID) override; /// Resolve a declaration ID into a declaration. Return 0 if it's not /// been loaded yet. @@ -1942,8 +1941,7 @@ public: /// /// \returns the global ID of the given declaration as known in the given /// module file. - LocalDeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M, - GlobalDeclID GlobalID); + DeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M, GlobalDeclID GlobalID); /// Reads a declaration ID from the given position in a record in the /// given module. diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 6c45b7348b85..d01b31549248 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -212,10 +212,10 @@ private: llvm::SmallVector DelayedNamespace; /// The first ID number we can use for our own declarations. - LocalDeclID FirstDeclID = LocalDeclID(clang::NUM_PREDEF_DECL_IDS); + DeclID FirstDeclID = clang::NUM_PREDEF_DECL_IDS; /// The decl ID that will be assigned to the next new decl. - LocalDeclID NextDeclID = FirstDeclID; + DeclID NextDeclID = FirstDeclID; /// Map that provides the ID numbers of each declaration within /// the output stream, as well as those deserialized from a chained PCH. @@ -223,7 +223,7 @@ private: /// The ID numbers of declarations are consecutive (in order of /// discovery) and start at 2. 1 is reserved for the translation /// unit, while 0 is reserved for NULL. - llvm::DenseMap DeclIDs; + llvm::DenseMap DeclIDs; /// Offset of each declaration in the bitstream, indexed by /// the declaration's ID. @@ -233,8 +233,8 @@ private: /// are relative to this value. uint64_t DeclTypesBlockStartOffset = 0; - /// Sorted (by file offset) vector of pairs of file offset/LocalDeclID. - using LocDeclIDsTy = SmallVector, 64>; + /// Sorted (by file offset) vector of pairs of file offset/DeclID. + using LocDeclIDsTy = SmallVector, 64>; struct DeclIDInFileInfo { LocDeclIDsTy DeclIDs; @@ -249,7 +249,7 @@ private: /// that it contains. FileDeclIDsTy FileDeclIDs; - void associateDeclWithFile(const Decl *D, LocalDeclID); + void associateDeclWithFile(const Decl *D, DeclID); /// The first ID number we can use for our own types. serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS; @@ -420,8 +420,8 @@ private: /// headers. The declarations themselves are stored as declaration /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS /// record. - RecordData EagerlyDeserializedDecls; - RecordData ModularCodegenDecls; + SmallVector EagerlyDeserializedDecls; + SmallVector ModularCodegenDecls; /// DeclContexts that have received extensions since their serialized /// form. @@ -707,8 +707,7 @@ public: if (D->isFromASTFile()) return false; auto I = DeclIDs.find(D); - return (I == DeclIDs.end() || - I->second.get() >= clang::NUM_PREDEF_DECL_IDS); + return (I == DeclIDs.end() || I->second >= clang::NUM_PREDEF_DECL_IDS); }; /// Emit a reference to a declaration. @@ -716,13 +715,12 @@ public: // Emit a reference to a declaration if the declaration was emitted. void AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record); - /// Force a declaration to be emitted and get its local ID to the module file - /// been writing. - LocalDeclID GetDeclRef(const Decl *D); + /// Force a declaration to be emitted and get its ID. + DeclID GetDeclRef(const Decl *D); - /// Determine the local declaration ID of an already-emitted + /// Determine the declaration ID of an already-emitted /// declaration. - LocalDeclID getDeclID(const Decl *D); + DeclID getDeclID(const Decl *D); /// Whether or not the declaration got emitted. If not, it wouldn't be /// emitted. diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 25f644e76edb..1f7222655876 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -459,10 +459,10 @@ public: const DeclOffset *DeclOffsets = nullptr; /// Base declaration ID for declarations local to this module. - serialization::DeclID BaseDeclID = 0; + DeclID BaseDeclID = 0; /// Remapping table for declaration IDs in this module. - ContinuousRangeMap DeclRemap; + ContinuousRangeMap DeclRemap; /// Mapping from the module files that this module file depends on /// to the base declaration ID for that module as it is understood within this @@ -471,7 +471,7 @@ public: /// This is effectively a reverse global-to-local mapping for declaration /// IDs, so that we can interpret a true global ID (for this translation unit) /// as a local ID (for this module file). - llvm::DenseMap GlobalToLocalDeclIDs; + llvm::DenseMap GlobalToLocalDeclIDs; /// Array of file-level DeclIDs sorted by file. const LocalDeclID *FileSortedDecls = nullptr; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 475b47afa639..a7386f755ca0 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1083,8 +1083,7 @@ void ASTContext::addModuleInitializer(Module *M, Decl *D) { Inits->Initializers.push_back(D); } -void ASTContext::addLazyModuleInitializers(Module *M, - ArrayRef IDs) { +void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef IDs) { auto *&Inits = ModuleInitializers[M]; if (!Inits) Inits = new (*this) PerModuleInitializers; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index e7e95c16b697..f452902110c7 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2151,7 +2151,7 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartL, return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S); } -VarDecl *VarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +VarDecl *VarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None); @@ -2929,7 +2929,7 @@ QualType ParmVarDecl::getOriginalType() const { return T; } -ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None, nullptr); @@ -4553,7 +4553,7 @@ FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC, BW, Mutable, InitStyle); } -FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, nullptr, false, ICIS_NoInit); @@ -4863,7 +4863,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, return Enum; } -EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, DeclID ID) { EnumDecl *Enum = new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr, false, false, false); @@ -5025,8 +5025,7 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, return R; } -RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, - GlobalDeclID ID) { +RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, DeclID ID) { RecordDecl *R = new (C, ID) RecordDecl(Record, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -5298,7 +5297,7 @@ PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, } PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID, + DeclID ID, unsigned ArgSize) { return new (C, ID, additionalSizeToAlloc(ArgSize + 1)) PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown); @@ -5323,7 +5322,7 @@ PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC, } PragmaDetectMismatchDecl * -PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, +PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NameValueSize) { return new (C, ID, additionalSizeToAlloc(NameValueSize + 1)) PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0); @@ -5350,7 +5349,7 @@ LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL); } -LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation()); } @@ -5391,7 +5390,7 @@ ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, QualType Type, } ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other); } @@ -5409,7 +5408,7 @@ FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, return New; } -FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) FunctionDecl( Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -5419,7 +5418,7 @@ BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) BlockDecl(DC, L); } -BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) BlockDecl(nullptr, SourceLocation()); } @@ -5433,7 +5432,7 @@ CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC, CapturedDecl(DC, NumParams); } -CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, +CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumParams) { return new (C, ID, additionalSizeToAlloc(NumParams)) CapturedDecl(nullptr, NumParams); @@ -5460,7 +5459,7 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, } EnumConstantDecl *EnumConstantDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) EnumConstantDecl(C, nullptr, SourceLocation(), nullptr, QualType(), nullptr, llvm::APSInt()); } @@ -5487,7 +5486,7 @@ IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) IndirectFieldDecl(C, nullptr, SourceLocation(), DeclarationName(), QualType(), std::nullopt); @@ -5548,7 +5547,7 @@ bool TypedefNameDecl::isTransparentTagSlow() const { return isTransparent; } -TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5561,8 +5560,7 @@ TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo); } -TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5593,7 +5591,7 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, } FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -5611,7 +5609,7 @@ TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) { } TopLevelStmtDecl *TopLevelStmtDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) TopLevelStmtDecl(/*DC=*/nullptr, SourceLocation(), /*S=*/nullptr); } @@ -5632,7 +5630,7 @@ EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) EmptyDecl(DC, L); } -EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) EmptyDecl(nullptr, SourceLocation()); } @@ -5665,8 +5663,7 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C, return Result; } -HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr, SourceLocation(), SourceLocation()); } @@ -5722,7 +5719,7 @@ ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC, return Import; } -ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, +ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumLocations) { return new (C, ID, additionalSizeToAlloc(NumLocations)) ImportDecl(EmptyShell()); @@ -5755,6 +5752,6 @@ ExportDecl *ExportDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) ExportDecl(DC, ExportLoc); } -ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ExportDecl(nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index c33babf8d1df..a2d88cf7a6a1 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -70,8 +70,8 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const { #define ABSTRACT_DECL(DECL) #include "clang/AST/DeclNodes.inc" -void *Decl::operator new(std::size_t Size, const ASTContext &Context, - GlobalDeclID ID, std::size_t Extra) { +void *Decl::operator new(std::size_t Size, const ASTContext &Context, DeclID ID, + std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. static_assert(sizeof(unsigned) * 2 >= alignof(Decl), @@ -85,7 +85,7 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, PrefixPtr[0] = 0; // Store the global declaration ID in the second 4 bytes. - PrefixPtr[1] = ID.get(); + PrefixPtr[1] = ID; return Result; } diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 75c441293d62..c525c3368ce2 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -57,8 +57,7 @@ using namespace clang; void AccessSpecDecl::anchor() {} -AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) AccessSpecDecl(EmptyShell()); } @@ -69,7 +68,7 @@ void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const { for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I) I.setDecl(cast(Source->GetExternalDecl( - GlobalDeclID(reinterpret_cast(I.getDecl()) >> 2)))); + reinterpret_cast(I.getDecl()) >> 2))); Impl.Decls.setLazy(false); } @@ -162,7 +161,7 @@ CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, } CXXRecordDecl *CXXRecordDecl::CreateDeserialized(const ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { auto *R = new (C, ID) CXXRecordDecl(CXXRecord, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -2163,8 +2162,8 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( TInfo, EndLocation, Ctor, Kind); } -CXXDeductionGuideDecl * -CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) CXXDeductionGuideDecl( C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), QualType(), nullptr, SourceLocation(), nullptr, @@ -2176,8 +2175,8 @@ RequiresExprBodyDecl *RequiresExprBodyDecl::Create( return new (C, DC) RequiresExprBodyDecl(C, DC, StartLoc); } -RequiresExprBodyDecl * -RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +RequiresExprBodyDecl *RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) RequiresExprBodyDecl(C, nullptr, SourceLocation()); } @@ -2282,8 +2281,7 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, isInline, ConstexprKind, EndLocation, TrailingRequiresClause); } -CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) CXXMethodDecl( CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, @@ -2701,7 +2699,7 @@ CXXConstructorDecl::CXXConstructorDecl( void CXXConstructorDecl::anchor() {} CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID, + DeclID ID, uint64_t AllocKind) { bool hasTrailingExplicit = static_cast(AllocKind & TAKHasTailExplicit); bool isInheritingConstructor = @@ -2848,7 +2846,7 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const { void CXXDestructorDecl::anchor() {} CXXDestructorDecl *CXXDestructorDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) CXXDestructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -2880,7 +2878,7 @@ void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) { void CXXConversionDecl::anchor() {} CXXConversionDecl *CXXConversionDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) CXXConversionDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified, @@ -2925,8 +2923,7 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces); } -LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(), SourceLocation(), LinkageSpecLanguageIDs::C, false); @@ -2948,7 +2945,7 @@ UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, } UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), @@ -2987,8 +2984,7 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, PrevDecl, Nested); } -NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(), SourceLocation(), nullptr, nullptr, false); } @@ -3050,7 +3046,7 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, } NamespaceAliasDecl *NamespaceAliasDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, NestedNameSpecifierLoc(), @@ -3105,8 +3101,7 @@ UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty) : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()), redeclarable_base(C) {} -UsingShadowDecl *UsingShadowDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +UsingShadowDecl *UsingShadowDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell()); } @@ -3129,7 +3124,7 @@ ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC, } ConstructorUsingShadowDecl * -ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell()); } @@ -3177,7 +3172,7 @@ UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL, return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename); } -UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UsingDecl(nullptr, SourceLocation(), NestedNameSpecifierLoc(), DeclarationNameInfo(), false); @@ -3201,8 +3196,7 @@ UsingEnumDecl *UsingEnumDecl::Create(ASTContext &C, DeclContext *DC, UsingEnumDecl(DC, EnumType->getType()->getAsTagDecl()->getDeclName(), UL, EL, NL, EnumType); } -UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UsingEnumDecl(nullptr, DeclarationName(), SourceLocation(), SourceLocation(), SourceLocation(), nullptr); @@ -3221,7 +3215,7 @@ UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls); } -UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, +UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumExpansions) { size_t Extra = additionalSizeToAlloc(NumExpansions); auto *Result = @@ -3247,7 +3241,7 @@ UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingValueDecl * -UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(), SourceLocation(), NestedNameSpecifierLoc(), @@ -3277,8 +3271,7 @@ UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingTypenameDecl * -UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UnresolvedUsingTypenameDecl( nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), nullptr, SourceLocation()); @@ -3291,8 +3284,7 @@ UnresolvedUsingIfExistsDecl::Create(ASTContext &Ctx, DeclContext *DC, } UnresolvedUsingIfExistsDecl * -UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, - GlobalDeclID ID) { +UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, DeclID ID) { return new (Ctx, ID) UnresolvedUsingIfExistsDecl(nullptr, SourceLocation(), DeclarationName()); } @@ -3316,7 +3308,7 @@ StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, } StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), false); } @@ -3338,7 +3330,7 @@ BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) BindingDecl(DC, IdLoc, Id); } -BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); } @@ -3369,7 +3361,7 @@ DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, } DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID, + DeclID ID, unsigned NumBindings) { size_t Extra = additionalSizeToAlloc(NumBindings); auto *Result = new (C, ID, Extra) @@ -3407,8 +3399,7 @@ MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) MSPropertyDecl(DC, L, N, T, TInfo, StartL, Getter, Setter); } -MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(), DeclarationName(), QualType(), nullptr, SourceLocation(), nullptr, nullptr); @@ -3425,7 +3416,7 @@ MSGuidDecl *MSGuidDecl::Create(const ASTContext &C, QualType T, Parts P) { return new (C, DC) MSGuidDecl(DC, T, P); } -MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) MSGuidDecl(nullptr, QualType(), Parts()); } @@ -3535,7 +3526,7 @@ UnnamedGlobalConstantDecl::Create(const ASTContext &C, QualType T, } UnnamedGlobalConstantDecl * -UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) UnnamedGlobalConstantDecl(C, nullptr, QualType(), APValue()); } diff --git a/clang/lib/AST/DeclFriend.cpp b/clang/lib/AST/DeclFriend.cpp index 04b9b93699f3..f6d11e550b57 100644 --- a/clang/lib/AST/DeclFriend.cpp +++ b/clang/lib/AST/DeclFriend.cpp @@ -62,7 +62,7 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, return FD; } -FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, +FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned FriendTypeNumTPLists) { std::size_t Extra = additionalSizeToAlloc(FriendTypeNumTPLists); diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 83062b0e6887..f98ec6727e48 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -862,8 +862,7 @@ ObjCMethodDecl *ObjCMethodDecl::Create( isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); } -ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(), Selector(), QualType(), nullptr, nullptr); } @@ -1487,7 +1486,7 @@ ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc, } ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx, - GlobalDeclID ID) { + DeclID ID) { return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr, ObjCTypeParamVariance::Invariant, SourceLocation(), 0, SourceLocation(), @@ -1552,7 +1551,7 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create( } ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { auto *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), nullptr, false); @@ -1866,7 +1865,7 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, synthesized); } -ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, ObjCIvarDecl::None, nullptr, false); @@ -1915,7 +1914,7 @@ ObjCAtDefsFieldDecl } ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr); @@ -1950,7 +1949,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, } ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { ObjCProtocolDecl *Result = new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(), SourceLocation(), nullptr); @@ -2149,7 +2148,7 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create( } ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(), SourceLocation(), SourceLocation(), nullptr, nullptr, nullptr); @@ -2189,8 +2188,8 @@ ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create( atStartLoc, CategoryNameLoc); } -ObjCCategoryImplDecl * -ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation(), SourceLocation()); @@ -2297,7 +2296,7 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, } ObjCImplementationDecl * -ObjCImplementationDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +ObjCImplementationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -2340,7 +2339,7 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, } ObjCCompatibleAliasDecl * -ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(), nullptr, nullptr); } @@ -2361,7 +2360,7 @@ ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr, SourceLocation(), SourceLocation(), QualType(), nullptr, None); @@ -2393,8 +2392,8 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, ivarLoc); } -ObjCPropertyImplDecl * -ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, Dynamic, nullptr, SourceLocation()); diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp index 81ca48e60942..9f1d2bd41235 100644 --- a/clang/lib/AST/DeclOpenMP.cpp +++ b/clang/lib/AST/DeclOpenMP.cpp @@ -35,9 +35,8 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C, return D; } -OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID, - unsigned N) { +OMPThreadPrivateDecl * +OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, 0, N); } @@ -63,8 +62,7 @@ OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC, return D; } -OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID, +OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NVars, unsigned NClauses) { return OMPDeclarativeDirective::createEmptyDirective( @@ -90,8 +88,7 @@ OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC, L); } -OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID, +OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 0, SourceLocation()); @@ -119,7 +116,7 @@ OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create( } OMPDeclareReductionDecl * -OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) OMPDeclareReductionDecl( OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(), QualType(), /*PrevDeclInScope=*/nullptr); @@ -149,9 +146,8 @@ OMPDeclareMapperDecl *OMPDeclareMapperDecl::Create( C, DC, Clauses, 1, L, Name, T, VarName, PrevDeclInScope); } -OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID, - unsigned N) { +OMPDeclareMapperDecl * +OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 1, SourceLocation(), DeclarationName(), QualType(), DeclarationName(), /*PrevDeclInScope=*/nullptr); @@ -181,7 +177,7 @@ OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC, } OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType(), /*TInfo=*/nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index d27a30e0c5fc..ca998b502bee 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -337,10 +337,9 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); if (CommonBasePtr->LazySpecializations) { ASTContext &Context = getASTContext(); - GlobalDeclID *Specs = CommonBasePtr->LazySpecializations; + DeclID *Specs = CommonBasePtr->LazySpecializations; CommonBasePtr->LazySpecializations = nullptr; - unsigned SpecSize = (*Specs++).get(); - for (unsigned I = 0; I != SpecSize; ++I) + for (uint32_t I = 0, N = *Specs++; I != N; ++I) (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); } } @@ -418,8 +417,8 @@ FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, return TD; } -FunctionTemplateDecl * -FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -504,7 +503,7 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC, } ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -653,14 +652,14 @@ TemplateTypeParmDecl *TemplateTypeParmDecl::Create( } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) { +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, DeclID ID) { return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, false, false, std::nullopt); } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID, +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, DeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc(HasTypeConstraint ? 1 : 0)) @@ -760,7 +759,7 @@ NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc, @@ -771,7 +770,7 @@ NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint) { auto *NTTP = @@ -837,13 +836,13 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, false, nullptr, false, nullptr); } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned NumExpansions) { auto *TTP = new (C, ID, additionalSizeToAlloc(NumExpansions)) @@ -949,8 +948,7 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, } ClassTemplateSpecializationDecl * -ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { auto *Result = new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); Result->setMayHaveOutOfDateDef(false); @@ -1036,7 +1034,7 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, return TD; } -ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, DeclID ID) { ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); @@ -1070,7 +1068,7 @@ ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( ImplicitConceptSpecializationDecl * ImplicitConceptSpecializationDecl::CreateDeserialized( - const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) { + const ASTContext &C, DeclID ID, unsigned NumTemplateArgs) { return new (C, ID, additionalSizeToAlloc(NumTemplateArgs)) ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); } @@ -1133,7 +1131,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, ClassTemplatePartialSpecializationDecl * ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); Result->setMayHaveOutOfDateDef(false); return Result; @@ -1160,7 +1158,7 @@ FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, } FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) FriendTemplateDecl(EmptyShell()); } @@ -1179,8 +1177,8 @@ TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, return TD; } -TypeAliasTemplateDecl * -TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, + DeclID ID) { return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1217,8 +1215,7 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, return TD; } -VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1340,8 +1337,7 @@ VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( } VarTemplateSpecializationDecl * -VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { +VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { return new (C, ID) VarTemplateSpecializationDecl(VarTemplateSpecialization, C); } @@ -1433,7 +1429,7 @@ VarTemplatePartialSpecializationDecl::Create( VarTemplatePartialSpecializationDecl * VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - GlobalDeclID ID) { + DeclID ID) { return new (C, ID) VarTemplatePartialSpecializationDecl(C); } @@ -1547,7 +1543,7 @@ TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C, } TemplateParamObjectDecl * -TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { +TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, DeclID ID) { auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue()); C.addDestruction(&TPOD->Value); return TPOD; diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index e96a47496851..26ded22bf329 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -68,7 +68,7 @@ bool ExternalASTSource::layoutRecordType( return false; } -Decl *ExternalASTSource::GetExternalDecl(GlobalDeclID ID) { return nullptr; } +Decl *ExternalASTSource::GetExternalDecl(DeclID ID) { return nullptr; } Selector ExternalASTSource::GetExternalSelector(uint32_t ID) { return Selector(); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 2f75313e8a4c..361331de145b 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1067,7 +1067,7 @@ public: std::vector takeTopLevelDecls() { return std::move(TopLevelDecls); } - std::vector takeTopLevelDeclIDs() { + std::vector takeTopLevelDeclIDs() { return std::move(TopLevelDeclIDs); } @@ -1101,7 +1101,7 @@ public: private: unsigned Hash = 0; std::vector TopLevelDecls; - std::vector TopLevelDeclIDs; + std::vector TopLevelDeclIDs; llvm::SmallVector PreambleDiags; }; @@ -1471,9 +1471,7 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() { for (const auto TopLevelDecl : TopLevelDeclsInPreamble) { // Resolve the declaration ID to an actual declaration, possibly // deserializing the declaration in the process. - // - // FIMXE: We shouldn't convert a LocalDeclID to GlobalDeclID directly. - if (Decl *D = Source.GetExternalDecl(GlobalDeclID(TopLevelDecl.get()))) + if (Decl *D = Source.GetExternalDecl(TopLevelDecl)) Resolved.push_back(D); } TopLevelDeclsInPreamble.clear(); diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index a2af738a053e..91ce16e5e795 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -80,7 +80,7 @@ public: if (Previous) Previous->TypeRead(Idx, T); } - void DeclRead(GlobalDeclID ID, const Decl *D) override { + void DeclRead(DeclID ID, const Decl *D) override { if (Previous) Previous->DeclRead(ID, D); } @@ -102,7 +102,7 @@ public: bool DeletePrevious) : DelegatingDeserializationListener(Previous, DeletePrevious) {} - void DeclRead(GlobalDeclID ID, const Decl *D) override { + void DeclRead(DeclID ID, const Decl *D) override { llvm::outs() << "PCH DECL: " << D->getDeclKindName(); if (const NamedDecl *ND = dyn_cast(D)) { llvm::outs() << " - "; @@ -128,7 +128,7 @@ public: : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx), NamesToCheck(NamesToCheck) {} - void DeclRead(GlobalDeclID ID, const Decl *D) override { + void DeclRead(DeclID ID, const Decl *D) override { if (const NamedDecl *ND = dyn_cast(D)) if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { unsigned DiagID diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index c74bfd86195f..9e885c8dc0f6 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -52,8 +52,7 @@ void MultiplexASTDeserializationListener::TypeRead( Listeners[i]->TypeRead(Idx, T); } -void MultiplexASTDeserializationListener::DeclRead(GlobalDeclID ID, - const Decl *D) { +void MultiplexASTDeserializationListener::DeclRead(DeclID ID, const Decl *D) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->DeclRead(ID, D); } diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index 79e656eb4b7e..e48c72498389 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -46,7 +46,7 @@ void MultiplexExternalSemaSource::AddSource(ExternalSemaSource *Source) { // ExternalASTSource. //===----------------------------------------------------------------------===// -Decl *MultiplexExternalSemaSource::GetExternalDecl(GlobalDeclID ID) { +Decl *MultiplexExternalSemaSource::GetExternalDecl(DeclID ID) { for(size_t i = 0; i < Sources.size(); ++i) if (Decl *Result = Sources[i]->GetExternalDecl(ID)) return Result; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index c99d6ed1c36c..df9984d537bf 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -5101,9 +5101,8 @@ void ASTReader::InitializeContext() { // If there's a listener, notify them that we "read" the translation unit. if (DeserializationListener) - DeserializationListener->DeclRead( - GlobalDeclID(PREDEF_DECL_TRANSLATION_UNIT_ID), - Context.getTranslationUnitDecl()); + DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, + Context.getTranslationUnitDecl()); // FIXME: Find a better way to deal with collisions between these // built-in types. Right now, we just ignore the problem. @@ -6011,9 +6010,9 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F, case SUBMODULE_INITIALIZERS: { if (!ContextObj) break; - SmallVector Inits; + SmallVector Inits; for (auto &ID : Record) - Inits.push_back(getGlobalDeclID(F, LocalDeclID(ID))); + Inits.push_back(getGlobalDeclID(F, LocalDeclID(ID)).get()); ContextObj->addLazyModuleInitializers(CurrentModule, Inits); break; } @@ -7518,7 +7517,9 @@ ASTRecordReader::readASTTemplateArgumentListInfo() { return ASTTemplateArgumentListInfo::Create(getContext(), Result); } -Decl *ASTReader::GetExternalDecl(GlobalDeclID ID) { return GetDecl(ID); } +Decl *ASTReader::GetExternalDecl(DeclID ID) { + return GetDecl(GlobalDeclID(ID)); +} void ASTReader::CompleteRedeclChain(const Decl *D) { if (NumCurrentElementsDeserializing) { @@ -7766,7 +7767,7 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { assert(ContextObj && "reading decl with no AST context"); if (ID.get() < NUM_PREDEF_DECL_IDS) { - Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID); + Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID.get()); if (D) { // Track that we have merged the declaration with ID \p ID into the // pre-existing predefined declaration \p D. @@ -7803,17 +7804,17 @@ Decl *ASTReader::GetDecl(GlobalDeclID ID) { if (!DeclsLoaded[Index]) { ReadDeclRecord(ID); if (DeserializationListener) - DeserializationListener->DeclRead(ID, DeclsLoaded[Index]); + DeserializationListener->DeclRead(ID.get(), DeclsLoaded[Index]); } return DeclsLoaded[Index]; } -LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, - GlobalDeclID GlobalID) { +DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + GlobalDeclID GlobalID) { DeclID ID = GlobalID.get(); if (ID < NUM_PREDEF_DECL_IDS) - return LocalDeclID(ID); + return ID; GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID); assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); @@ -7822,9 +7823,9 @@ LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, llvm::DenseMap::iterator Pos = M.GlobalToLocalDeclIDs.find(Owner); if (Pos == M.GlobalToLocalDeclIDs.end()) - return LocalDeclID(); + return 0; - return LocalDeclID(ID - Owner->BaseDeclID + Pos->second); + return ID - Owner->BaseDeclID + Pos->second; } GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordData &Record, @@ -7991,7 +7992,6 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, // Load the list of declarations. SmallVector Decls; llvm::SmallPtrSet Found; - for (GlobalDeclID ID : It->second.Table.find(Name)) { NamedDecl *ND = cast(GetDecl(ID)); if (ND->getDeclName() == Name && Found.insert(ND).second) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 744f11de88c2..9707eed701e9 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -273,15 +273,17 @@ namespace clang { auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations; if (auto &Old = LazySpecializations) { - IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0].get()); + IDs.insert(IDs.end(), GlobalDeclIDIterator(Old + 1), + GlobalDeclIDIterator(Old + 1 + Old[0])); llvm::sort(IDs); IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); } - auto *Result = new (C) GlobalDeclID[1 + IDs.size()]; - *Result = GlobalDeclID(IDs.size()); + auto *Result = new (C) DeclID[1 + IDs.size()]; + *Result = IDs.size(); - std::copy(IDs.begin(), IDs.end(), Result + 1); + std::copy(DeclIDIterator(IDs.begin()), DeclIDIterator(IDs.end()), + Result + 1); LazySpecializations = Result; } @@ -556,7 +558,7 @@ void ASTDeclReader::Visit(Decl *D) { // If this is a tag declaration with a typedef name for linkage, it's safe // to load that typedef now. - if (NamedDeclForTagDecl.isValid()) + if (NamedDeclForTagDecl != GlobalDeclID()) cast(D)->TypedefNameDeclOrQualifier = cast(Reader.GetDecl(NamedDeclForTagDecl)); } else if (auto *ID = dyn_cast(D)) { @@ -601,7 +603,7 @@ void ASTDeclReader::VisitDecl(Decl *D) { GlobalDeclID SemaDCIDForTemplateParmDecl = readDeclID(); GlobalDeclID LexicalDCIDForTemplateParmDecl = HasStandaloneLexicalDC ? readDeclID() : GlobalDeclID(); - if (LexicalDCIDForTemplateParmDecl.isInvalid()) + if (LexicalDCIDForTemplateParmDecl == GlobalDeclID()) LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl; Reader.addPendingDeclContextInfo(D, SemaDCIDForTemplateParmDecl, @@ -1858,7 +1860,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { mergeRedeclarable(D, Redecl); - if (AnonNamespace.isValid()) { + if (AnonNamespace != GlobalDeclID()) { // Each module has its own anonymous namespace, which is disjoint from // any other module's anonymous namespaces, so don't attach the anonymous // namespace at all. @@ -2790,9 +2792,9 @@ ASTDeclReader::VisitRedeclarable(Redeclarable *D) { uint64_t RedeclOffset = 0; - // invalid FirstDeclID indicates that this declaration was the only - // declaration of its entity, and is used for space optimization. - if (FirstDeclID.isInvalid()) { + // 0 indicates that this declaration was the only declaration of its entity, + // and is used for space optimization. + if (FirstDeclID == GlobalDeclID()) { FirstDeclID = ThisDeclID; IsKeyDecl = true; IsFirstLocalDecl = true; @@ -3827,232 +3829,240 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { Twine("ASTReader::readDeclRecord failed reading decl code: ") + toString(MaybeDeclCode.takeError())); + DeclID RawGlobalID = ID.get(); switch ((DeclCode)MaybeDeclCode.get()) { case DECL_CONTEXT_LEXICAL: case DECL_CONTEXT_VISIBLE: llvm_unreachable("Record cannot be de-serialized with readDeclRecord"); case DECL_TYPEDEF: - D = TypedefDecl::CreateDeserialized(Context, ID); + D = TypedefDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_TYPEALIAS: - D = TypeAliasDecl::CreateDeserialized(Context, ID); + D = TypeAliasDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_ENUM: - D = EnumDecl::CreateDeserialized(Context, ID); + D = EnumDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_RECORD: - D = RecordDecl::CreateDeserialized(Context, ID); + D = RecordDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_ENUM_CONSTANT: - D = EnumConstantDecl::CreateDeserialized(Context, ID); + D = EnumConstantDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_FUNCTION: - D = FunctionDecl::CreateDeserialized(Context, ID); + D = FunctionDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_LINKAGE_SPEC: - D = LinkageSpecDecl::CreateDeserialized(Context, ID); + D = LinkageSpecDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_EXPORT: - D = ExportDecl::CreateDeserialized(Context, ID); + D = ExportDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_LABEL: - D = LabelDecl::CreateDeserialized(Context, ID); + D = LabelDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_NAMESPACE: - D = NamespaceDecl::CreateDeserialized(Context, ID); + D = NamespaceDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_NAMESPACE_ALIAS: - D = NamespaceAliasDecl::CreateDeserialized(Context, ID); + D = NamespaceAliasDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_USING: - D = UsingDecl::CreateDeserialized(Context, ID); + D = UsingDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_USING_PACK: - D = UsingPackDecl::CreateDeserialized(Context, ID, Record.readInt()); + D = UsingPackDecl::CreateDeserialized(Context, RawGlobalID, + Record.readInt()); break; case DECL_USING_SHADOW: - D = UsingShadowDecl::CreateDeserialized(Context, ID); + D = UsingShadowDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_USING_ENUM: - D = UsingEnumDecl::CreateDeserialized(Context, ID); + D = UsingEnumDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CONSTRUCTOR_USING_SHADOW: - D = ConstructorUsingShadowDecl::CreateDeserialized(Context, ID); + D = ConstructorUsingShadowDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_USING_DIRECTIVE: - D = UsingDirectiveDecl::CreateDeserialized(Context, ID); + D = UsingDirectiveDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_UNRESOLVED_USING_VALUE: - D = UnresolvedUsingValueDecl::CreateDeserialized(Context, ID); + D = UnresolvedUsingValueDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_UNRESOLVED_USING_TYPENAME: - D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, ID); + D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_UNRESOLVED_USING_IF_EXISTS: - D = UnresolvedUsingIfExistsDecl::CreateDeserialized(Context, ID); + D = UnresolvedUsingIfExistsDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CXX_RECORD: - D = CXXRecordDecl::CreateDeserialized(Context, ID); + D = CXXRecordDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CXX_DEDUCTION_GUIDE: - D = CXXDeductionGuideDecl::CreateDeserialized(Context, ID); + D = CXXDeductionGuideDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CXX_METHOD: - D = CXXMethodDecl::CreateDeserialized(Context, ID); + D = CXXMethodDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CXX_CONSTRUCTOR: - D = CXXConstructorDecl::CreateDeserialized(Context, ID, Record.readInt()); + D = CXXConstructorDecl::CreateDeserialized(Context, RawGlobalID, + Record.readInt()); break; case DECL_CXX_DESTRUCTOR: - D = CXXDestructorDecl::CreateDeserialized(Context, ID); + D = CXXDestructorDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CXX_CONVERSION: - D = CXXConversionDecl::CreateDeserialized(Context, ID); + D = CXXConversionDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_ACCESS_SPEC: - D = AccessSpecDecl::CreateDeserialized(Context, ID); + D = AccessSpecDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_FRIEND: - D = FriendDecl::CreateDeserialized(Context, ID, Record.readInt()); + D = FriendDecl::CreateDeserialized(Context, RawGlobalID, Record.readInt()); break; case DECL_FRIEND_TEMPLATE: - D = FriendTemplateDecl::CreateDeserialized(Context, ID); + D = FriendTemplateDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CLASS_TEMPLATE: - D = ClassTemplateDecl::CreateDeserialized(Context, ID); + D = ClassTemplateDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CLASS_TEMPLATE_SPECIALIZATION: - D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, ID); + D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, + RawGlobalID); break; case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION: - D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); + D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, + RawGlobalID); break; case DECL_VAR_TEMPLATE: - D = VarTemplateDecl::CreateDeserialized(Context, ID); + D = VarTemplateDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_VAR_TEMPLATE_SPECIALIZATION: - D = VarTemplateSpecializationDecl::CreateDeserialized(Context, ID); + D = VarTemplateSpecializationDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION: - D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); + D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, + RawGlobalID); break; case DECL_FUNCTION_TEMPLATE: - D = FunctionTemplateDecl::CreateDeserialized(Context, ID); + D = FunctionTemplateDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_TEMPLATE_TYPE_PARM: { bool HasTypeConstraint = Record.readInt(); - D = TemplateTypeParmDecl::CreateDeserialized(Context, ID, + D = TemplateTypeParmDecl::CreateDeserialized(Context, RawGlobalID, HasTypeConstraint); break; } case DECL_NON_TYPE_TEMPLATE_PARM: { bool HasTypeConstraint = Record.readInt(); - D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, + D = NonTypeTemplateParmDecl::CreateDeserialized(Context, RawGlobalID, HasTypeConstraint); break; } case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: { bool HasTypeConstraint = Record.readInt(); D = NonTypeTemplateParmDecl::CreateDeserialized( - Context, ID, Record.readInt(), HasTypeConstraint); + Context, RawGlobalID, Record.readInt(), HasTypeConstraint); break; } case DECL_TEMPLATE_TEMPLATE_PARM: - D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID); + D = TemplateTemplateParmDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK: - D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID, + D = TemplateTemplateParmDecl::CreateDeserialized(Context, RawGlobalID, Record.readInt()); break; case DECL_TYPE_ALIAS_TEMPLATE: - D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID); + D = TypeAliasTemplateDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CONCEPT: - D = ConceptDecl::CreateDeserialized(Context, ID); + D = ConceptDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_REQUIRES_EXPR_BODY: - D = RequiresExprBodyDecl::CreateDeserialized(Context, ID); + D = RequiresExprBodyDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_STATIC_ASSERT: - D = StaticAssertDecl::CreateDeserialized(Context, ID); + D = StaticAssertDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_METHOD: - D = ObjCMethodDecl::CreateDeserialized(Context, ID); + D = ObjCMethodDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_INTERFACE: - D = ObjCInterfaceDecl::CreateDeserialized(Context, ID); + D = ObjCInterfaceDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_IVAR: - D = ObjCIvarDecl::CreateDeserialized(Context, ID); + D = ObjCIvarDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_PROTOCOL: - D = ObjCProtocolDecl::CreateDeserialized(Context, ID); + D = ObjCProtocolDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_AT_DEFS_FIELD: - D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, ID); + D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_CATEGORY: - D = ObjCCategoryDecl::CreateDeserialized(Context, ID); + D = ObjCCategoryDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_CATEGORY_IMPL: - D = ObjCCategoryImplDecl::CreateDeserialized(Context, ID); + D = ObjCCategoryImplDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_IMPLEMENTATION: - D = ObjCImplementationDecl::CreateDeserialized(Context, ID); + D = ObjCImplementationDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_COMPATIBLE_ALIAS: - D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, ID); + D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_PROPERTY: - D = ObjCPropertyDecl::CreateDeserialized(Context, ID); + D = ObjCPropertyDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_PROPERTY_IMPL: - D = ObjCPropertyImplDecl::CreateDeserialized(Context, ID); + D = ObjCPropertyImplDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_FIELD: - D = FieldDecl::CreateDeserialized(Context, ID); + D = FieldDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_INDIRECTFIELD: - D = IndirectFieldDecl::CreateDeserialized(Context, ID); + D = IndirectFieldDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_VAR: - D = VarDecl::CreateDeserialized(Context, ID); + D = VarDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_IMPLICIT_PARAM: - D = ImplicitParamDecl::CreateDeserialized(Context, ID); + D = ImplicitParamDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_PARM_VAR: - D = ParmVarDecl::CreateDeserialized(Context, ID); + D = ParmVarDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_DECOMPOSITION: - D = DecompositionDecl::CreateDeserialized(Context, ID, Record.readInt()); + D = DecompositionDecl::CreateDeserialized(Context, RawGlobalID, + Record.readInt()); break; case DECL_BINDING: - D = BindingDecl::CreateDeserialized(Context, ID); + D = BindingDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_FILE_SCOPE_ASM: - D = FileScopeAsmDecl::CreateDeserialized(Context, ID); + D = FileScopeAsmDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_TOP_LEVEL_STMT_DECL: - D = TopLevelStmtDecl::CreateDeserialized(Context, ID); + D = TopLevelStmtDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_BLOCK: - D = BlockDecl::CreateDeserialized(Context, ID); + D = BlockDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_MS_PROPERTY: - D = MSPropertyDecl::CreateDeserialized(Context, ID); + D = MSPropertyDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_MS_GUID: - D = MSGuidDecl::CreateDeserialized(Context, ID); + D = MSGuidDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_UNNAMED_GLOBAL_CONSTANT: - D = UnnamedGlobalConstantDecl::CreateDeserialized(Context, ID); + D = UnnamedGlobalConstantDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_TEMPLATE_PARAM_OBJECT: - D = TemplateParamObjectDecl::CreateDeserialized(Context, ID); + D = TemplateParamObjectDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_CAPTURED: - D = CapturedDecl::CreateDeserialized(Context, ID, Record.readInt()); + D = CapturedDecl::CreateDeserialized(Context, RawGlobalID, + Record.readInt()); break; case DECL_CXX_BASE_SPECIFIERS: Error("attempt to read a C++ base-specifier record as a declaration"); @@ -4063,62 +4073,66 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { case DECL_IMPORT: // Note: last entry of the ImportDecl record is the number of stored source // locations. - D = ImportDecl::CreateDeserialized(Context, ID, Record.back()); + D = ImportDecl::CreateDeserialized(Context, RawGlobalID, Record.back()); break; case DECL_OMP_THREADPRIVATE: { Record.skipInts(1); unsigned NumChildren = Record.readInt(); Record.skipInts(1); - D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, NumChildren); + D = OMPThreadPrivateDecl::CreateDeserialized(Context, RawGlobalID, + NumChildren); break; } case DECL_OMP_ALLOCATE: { unsigned NumClauses = Record.readInt(); unsigned NumVars = Record.readInt(); Record.skipInts(1); - D = OMPAllocateDecl::CreateDeserialized(Context, ID, NumVars, NumClauses); + D = OMPAllocateDecl::CreateDeserialized(Context, RawGlobalID, NumVars, + NumClauses); break; } case DECL_OMP_REQUIRES: { unsigned NumClauses = Record.readInt(); Record.skipInts(2); - D = OMPRequiresDecl::CreateDeserialized(Context, ID, NumClauses); + D = OMPRequiresDecl::CreateDeserialized(Context, RawGlobalID, NumClauses); break; } case DECL_OMP_DECLARE_REDUCTION: - D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID); + D = OMPDeclareReductionDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OMP_DECLARE_MAPPER: { unsigned NumClauses = Record.readInt(); Record.skipInts(2); - D = OMPDeclareMapperDecl::CreateDeserialized(Context, ID, NumClauses); + D = OMPDeclareMapperDecl::CreateDeserialized(Context, RawGlobalID, + NumClauses); break; } case DECL_OMP_CAPTUREDEXPR: - D = OMPCapturedExprDecl::CreateDeserialized(Context, ID); + D = OMPCapturedExprDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_PRAGMA_COMMENT: - D = PragmaCommentDecl::CreateDeserialized(Context, ID, Record.readInt()); + D = PragmaCommentDecl::CreateDeserialized(Context, RawGlobalID, + Record.readInt()); break; case DECL_PRAGMA_DETECT_MISMATCH: - D = PragmaDetectMismatchDecl::CreateDeserialized(Context, ID, + D = PragmaDetectMismatchDecl::CreateDeserialized(Context, RawGlobalID, Record.readInt()); break; case DECL_EMPTY: - D = EmptyDecl::CreateDeserialized(Context, ID); + D = EmptyDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_LIFETIME_EXTENDED_TEMPORARY: - D = LifetimeExtendedTemporaryDecl::CreateDeserialized(Context, ID); + D = LifetimeExtendedTemporaryDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_OBJC_TYPE_PARAM: - D = ObjCTypeParamDecl::CreateDeserialized(Context, ID); + D = ObjCTypeParamDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_HLSL_BUFFER: - D = HLSLBufferDecl::CreateDeserialized(Context, ID); + D = HLSLBufferDecl::CreateDeserialized(Context, RawGlobalID); break; case DECL_IMPLICIT_CONCEPT_SPECIALIZATION: - D = ImplicitConceptSpecializationDecl::CreateDeserialized(Context, ID, - Record.readInt()); + D = ImplicitConceptSpecializationDecl::CreateDeserialized( + Context, RawGlobalID, Record.readInt()); break; } @@ -4410,9 +4424,8 @@ namespace { // Map global ID of the definition down to the local ID used in this // module file. If there is no such mapping, we'll find nothing here // (or in any module it imports). - LocalDeclID LocalID = - Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID); - if (LocalID.isInvalid()) + DeclID LocalID = Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID); + if (!LocalID) return true; // Perform a binary search to find the local redeclarations for this diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 0408eeb6a95b..842ea58656ad 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3043,7 +3043,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { RecordData Inits; for (Decl *D : Context->getModuleInitializers(Mod)) if (wasDeclEmitted(D)) - AddDeclRef(D, Inits); + Inits.push_back(GetDeclRef(D)); if (!Inits.empty()) Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits); @@ -3226,7 +3226,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, continue; KindDeclPairs.push_back(D->getKind()); - KindDeclPairs.push_back(GetDeclRef(D).get()); + KindDeclPairs.push_back(GetDeclRef(D)); } ++NumLexicalDeclContexts; @@ -3261,7 +3261,7 @@ void ASTWriter::WriteTypeDeclOffsets() { unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); { RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(), - FirstDeclID.get() - NUM_PREDEF_DECL_IDS}; + FirstDeclID - NUM_PREDEF_DECL_IDS}; Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets)); } } @@ -3282,7 +3282,7 @@ void ASTWriter::WriteFileDeclIDsMap() { Info.FirstDeclIndex = FileGroupedDeclIDs.size(); llvm::stable_sort(Info.DeclIDs); for (auto &LocDeclEntry : Info.DeclIDs) - FileGroupedDeclIDs.push_back(LocDeclEntry.second.get()); + FileGroupedDeclIDs.push_back(LocDeclEntry.second); } auto Abbrev = std::make_shared(); @@ -3420,11 +3420,11 @@ public: for (const ObjCMethodList *Method = &Methods.Instance; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - LE.write((DeclID)Writer.getDeclID(Method->getMethod())); + LE.write(Writer.getDeclID(Method->getMethod())); for (const ObjCMethodList *Method = &Methods.Factory; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - LE.write((DeclID)Writer.getDeclID(Method->getMethod())); + LE.write(Writer.getDeclID(Method->getMethod())); assert(Out.tell() - Start == DataLen && "Data length is wrong"); } @@ -3743,8 +3743,8 @@ public: // Only emit declarations that aren't from a chained PCH, though. SmallVector Decls(IdResolver.decls(II)); for (NamedDecl *D : llvm::reverse(Decls)) - LE.write((DeclID)Writer.getDeclID( - getDeclForLocalLookup(PP.getLangOpts(), D))); + LE.write( + Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), D))); } } }; @@ -3860,7 +3860,7 @@ namespace { // Trait used for the on-disk hash table used in the method pool. class ASTDeclContextNameLookupTrait { ASTWriter &Writer; - llvm::SmallVector DeclIDs; + llvm::SmallVector DeclIDs; public: using key_type = DeclarationNameKey; @@ -3893,10 +3893,8 @@ public: data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) { unsigned Start = DeclIDs.size(); - DeclIDs.insert( - DeclIDs.end(), - DeclIDIterator(FromReader.begin()), - DeclIDIterator(FromReader.end())); + DeclIDs.insert(DeclIDs.end(), DeclIDIterator(FromReader.begin()), + DeclIDIterator(FromReader.end())); return std::make_pair(Start, DeclIDs.size()); } @@ -3985,7 +3983,7 @@ public: endian::Writer LE(Out, llvm::endianness::little); uint64_t Start = Out.tell(); (void)Start; for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) - LE.write((DeclID)DeclIDs[I]); + LE.write(DeclIDs[I]); assert(Out.tell() - Start == DataLen && "Data length is wrong"); } }; @@ -4319,8 +4317,7 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { DC = cast(Chain->getKeyDeclaration(cast(DC))); // Write the lookup table - RecordData::value_type Record[] = {UPDATE_VISIBLE, - getDeclID(cast(DC)).get()}; + RecordData::value_type Record[] = {UPDATE_VISIBLE, getDeclID(cast(DC))}; Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable); } @@ -4374,7 +4371,7 @@ void ASTWriter::WriteObjCCategories() { Cat = Class->known_categories_begin(), CatEnd = Class->known_categories_end(); Cat != CatEnd; ++Cat, ++Size) { - assert(getDeclID(*Cat).isValid() && "Bogus category"); + assert(getDeclID(*Cat) != 0 && "Bogus category"); AddDeclRef(*Cat, Categories); } @@ -5092,7 +5089,7 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) { if (!D || !wasDeclEmitted(D)) SemaDeclRefs.push_back(0); else - AddDeclRef(D, SemaDeclRefs); + SemaDeclRefs.push_back(getDeclID(D)); }; AddEmittedDeclRefOrZero(SemaRef.getStdNamespace()); @@ -5103,10 +5100,10 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) { Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); // Write the record containing decls to be checked for deferred diags. - RecordData DeclsToCheckForDeferredDiags; + SmallVector DeclsToCheckForDeferredDiags; for (auto *D : SemaRef.DeclsToCheckForDeferredDiags) if (wasDeclEmitted(D)) - AddDeclRef(D, DeclsToCheckForDeferredDiags); + DeclsToCheckForDeferredDiags.push_back(getDeclID(D)); if (!DeclsToCheckForDeferredDiags.empty()) Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS, DeclsToCheckForDeferredDiags); @@ -5476,7 +5473,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { if (VisibleOffset) VisibleOffset -= DeclTypesBlockStartOffset; - AddDeclRef(NS, DelayedNamespaceRecord); + DelayedNamespaceRecord.push_back(getDeclID(NS)); DelayedNamespaceRecord.push_back(LexicalOffset); DelayedNamespaceRecord.push_back(VisibleOffset); } @@ -5510,7 +5507,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { continue; NewGlobalKindDeclPairs.push_back(D->getKind()); - NewGlobalKindDeclPairs.push_back(GetDeclRef(D).get()); + NewGlobalKindDeclPairs.push_back(GetDeclRef(D)); } auto Abv = std::make_shared(); @@ -5571,7 +5568,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: assert(Update.getDecl() && "no decl to add?"); - Record.AddDeclRef(Update.getDecl()); + Record.push_back(GetDeclRef(Update.getDecl())); break; case UPD_CXX_ADDED_FUNCTION_DEFINITION: @@ -5712,7 +5709,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { } } - AddDeclRef(D, OffsetsRecord); + OffsetsRecord.push_back(GetDeclRef(D)); OffsetsRecord.push_back(Record.Emit(DECL_UPDATES)); } } @@ -5977,18 +5974,18 @@ void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) { if (!wasDeclEmitted(D)) return; - Record.push_back(GetDeclRef(D).get()); + Record.push_back(GetDeclRef(D)); } void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { - Record.push_back(GetDeclRef(D).get()); + Record.push_back(GetDeclRef(D)); } -LocalDeclID ASTWriter::GetDeclRef(const Decl *D) { +DeclID ASTWriter::GetDeclRef(const Decl *D) { assert(WritingAST && "Cannot request a declaration ID before AST writing"); if (!D) { - return LocalDeclID(); + return 0; } // If the DeclUpdate from the GMF gets touched, emit it. @@ -6002,14 +5999,14 @@ LocalDeclID ASTWriter::GetDeclRef(const Decl *D) { // If D comes from an AST file, its declaration ID is already known and // fixed. if (D->isFromASTFile()) - return LocalDeclID(D->getGlobalID()); + return D->getGlobalID(); assert(!(reinterpret_cast(D) & 0x01) && "Invalid decl pointer"); - LocalDeclID &ID = DeclIDs[D]; - if (ID.isInvalid()) { + DeclID &ID = DeclIDs[D]; + if (ID == 0) { if (DoneWritingDeclsAndTypes) { assert(0 && "New decl seen after serializing all the decls to emit!"); - return LocalDeclID(); + return 0; } // We haven't seen this declaration before. Give it a new ID and @@ -6021,14 +6018,14 @@ LocalDeclID ASTWriter::GetDeclRef(const Decl *D) { return ID; } -LocalDeclID ASTWriter::getDeclID(const Decl *D) { +DeclID ASTWriter::getDeclID(const Decl *D) { if (!D) - return LocalDeclID(); + return 0; // If D comes from an AST file, its declaration ID is already known and // fixed. if (D->isFromASTFile()) - return LocalDeclID(D->getGlobalID()); + return D->getGlobalID(); assert(DeclIDs.contains(D) && "Declaration not emitted!"); return DeclIDs[D]; @@ -6049,8 +6046,8 @@ bool ASTWriter::wasDeclEmitted(const Decl *D) const { return Emitted; } -void ASTWriter::associateDeclWithFile(const Decl *D, LocalDeclID ID) { - assert(ID.isValid()); +void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { + assert(ID); assert(D); SourceLocation Loc = D->getLocation(); @@ -6082,7 +6079,7 @@ void ASTWriter::associateDeclWithFile(const Decl *D, LocalDeclID ID) { if (!Info) Info = std::make_unique(); - std::pair LocDecl(Offset, ID); + std::pair LocDecl(Offset, ID); LocDeclIDsTy &Decls = Info->DeclIDs; Decls.push_back(LocDecl); } @@ -6352,7 +6349,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType(); Record->push_back(ModulesDebugInfo); if (ModulesDebugInfo) - Writer->AddDeclRef(D, Writer->ModularCodegenDecls); + Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D)); // IsLambda bit is already saved. @@ -6456,7 +6453,7 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { // Note, this will get called multiple times, once one the reader starts up // and again each time it's done reading a PCH or module. - FirstDeclID = LocalDeclID(NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls()); + FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls(); FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros(); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 0edc4feda3ef..fe867192b717 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -223,9 +223,9 @@ namespace clang { assert(!Common->LazySpecializations); } - ArrayRef LazySpecializations; + ArrayRef LazySpecializations; if (auto *LS = Common->LazySpecializations) - LazySpecializations = llvm::ArrayRef(LS + 1, LS[0].get()); + LazySpecializations = llvm::ArrayRef(LS + 1, LS[0]); // Add a slot to the record for the number of specializations. unsigned I = Record.size(); @@ -243,9 +243,7 @@ namespace clang { assert(D->isCanonicalDecl() && "non-canonical decl in set"); AddFirstDeclFromEachModule(D, /*IncludeLocal*/true); } - Record.append( - DeclIDIterator(LazySpecializations.begin()), - DeclIDIterator(LazySpecializations.end())); + Record.append(LazySpecializations.begin(), LazySpecializations.end()); // Update the size entry we added earlier. Record[I] = Record.size() - I - 1; @@ -1168,7 +1166,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(VarDeclBits); if (ModulesCodegen) - Writer.AddDeclRef(D, Writer.ModularCodegenDecls); + Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D)); if (D->hasAttr()) { BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D); @@ -2788,10 +2786,10 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { "serializing"); // Determine the ID for this declaration. - LocalDeclID ID; + DeclID ID; assert(!D->isFromASTFile() && "should not be emitting imported decl"); - LocalDeclID &IDR = DeclIDs[D]; - if (IDR.isInvalid()) + DeclID &IDR = DeclIDs[D]; + if (IDR == 0) IDR = NextDeclID++; ID = IDR; @@ -2809,7 +2807,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Record the offset for this declaration SourceLocation Loc = D->getLocation(); - unsigned Index = ID.get() - FirstDeclID.get(); + unsigned Index = ID - FirstDeclID; if (DeclOffsets.size() == Index) DeclOffsets.emplace_back(getAdjustedLocation(Loc), Offset, DeclTypesBlockStartOffset); @@ -2829,7 +2827,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Note declarations that should be deserialized eagerly so that we can add // them to a record in the AST file later. if (isRequiredDecl(D, Context, WritingModule)) - AddDeclRef(D, EagerlyDeserializedDecls); + EagerlyDeserializedDecls.push_back(ID); } void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { @@ -2865,7 +2863,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { } Record->push_back(ModulesCodegen); if (ModulesCodegen) - Writer->AddDeclRef(FD, Writer->ModularCodegenDecls); + Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(FD)); if (auto *CD = dyn_cast(FD)) { Record->push_back(CD->getNumCtorInitializers()); if (CD->getNumCtorInitializers()) -- GitLab From d86cc73bbfd9a22d9a0d498d72c9b2ee235128e9 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Thu, 25 Apr 2024 11:43:13 +0800 Subject: [PATCH 059/733] [NFC] [Serialization] Avoid using DeclID directly as much as possible This patch tries to remove all the direct use of DeclID except the real low level reading and writing. All the use of DeclID is converted to the use of LocalDeclID or GlobalDeclID. This is helpful to increase the readability and type safety. --- clang/include/clang/AST/ASTContext.h | 4 +- clang/include/clang/AST/Decl.h | 46 ++-- clang/include/clang/AST/DeclBase.h | 8 +- clang/include/clang/AST/DeclCXX.h | 59 ++--- clang/include/clang/AST/DeclFriend.h | 2 +- clang/include/clang/AST/DeclID.h | 140 ++++++++---- clang/include/clang/AST/DeclObjC.h | 30 ++- clang/include/clang/AST/DeclOpenMP.h | 17 +- clang/include/clang/AST/DeclTemplate.h | 50 ++--- clang/include/clang/AST/ExternalASTSource.h | 6 +- clang/include/clang/Frontend/ASTUnit.h | 2 +- .../clang/Frontend/MultiplexConsumer.h | 2 +- .../clang/Sema/MultiplexExternalSemaSource.h | 2 +- .../include/clang/Serialization/ASTBitCodes.h | 27 +-- .../ASTDeserializationListener.h | 2 +- clang/include/clang/Serialization/ASTReader.h | 8 +- clang/include/clang/Serialization/ASTWriter.h | 28 +-- .../include/clang/Serialization/ModuleFile.h | 6 +- clang/lib/AST/ASTContext.cpp | 3 +- clang/lib/AST/Decl.cpp | 47 ++-- clang/lib/AST/DeclBase.cpp | 6 +- clang/lib/AST/DeclCXX.cpp | 67 +++--- clang/lib/AST/DeclFriend.cpp | 2 +- clang/lib/AST/DeclObjC.cpp | 29 +-- clang/lib/AST/DeclOpenMP.cpp | 20 +- clang/lib/AST/DeclTemplate.cpp | 48 ++-- clang/lib/AST/ExternalASTSource.cpp | 2 +- clang/lib/Frontend/ASTUnit.cpp | 8 +- clang/lib/Frontend/FrontendAction.cpp | 6 +- clang/lib/Frontend/MultiplexConsumer.cpp | 3 +- .../lib/Sema/MultiplexExternalSemaSource.cpp | 2 +- clang/lib/Serialization/ASTReader.cpp | 28 +-- clang/lib/Serialization/ASTReaderDecl.cpp | 211 ++++++++---------- clang/lib/Serialization/ASTWriter.cpp | 77 ++++--- clang/lib/Serialization/ASTWriterDecl.cpp | 22 +- .../Plugins/ExpressionParser/Clang/ASTUtils.h | 4 +- .../ExpressionParser/Clang/ClangASTSource.h | 2 +- .../TypeSystem/Clang/TypeSystemClang.cpp | 66 +++--- 38 files changed, 583 insertions(+), 509 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index ecec9bfcf300..24388ad5dea5 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -455,7 +455,7 @@ class ASTContext : public RefCountedBase { /// initialization of another module). struct PerModuleInitializers { llvm::SmallVector Initializers; - llvm::SmallVector LazyInitializers; + llvm::SmallVector LazyInitializers; void resolve(ASTContext &Ctx); }; @@ -1059,7 +1059,7 @@ public: /// or an ImportDecl nominating another module that has initializers. void addModuleInitializer(Module *M, Decl *Init); - void addLazyModuleInitializers(Module *M, ArrayRef IDs); + void addLazyModuleInitializers(Module *M, ArrayRef IDs); /// Get the initializations to perform when importing a module, if any. ArrayRef getModuleInitializers(Module *M); diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 8b121896d66d..a53c27a99a8c 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -157,7 +157,7 @@ public: SourceLocation CommentLoc, PragmaMSCommentKind CommentKind, StringRef Arg); - static PragmaCommentDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static PragmaCommentDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned ArgSize); PragmaMSCommentKind getCommentKind() const { return CommentKind; } @@ -192,7 +192,7 @@ public: SourceLocation Loc, StringRef Name, StringRef Value); static PragmaDetectMismatchDecl * - CreateDeserialized(ASTContext &C, DeclID ID, unsigned NameValueSize); + CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize); StringRef getName() const { return getTrailingObjects(); } StringRef getValue() const { return getTrailingObjects() + ValueStart; } @@ -518,7 +518,7 @@ public: static LabelDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, SourceLocation GnuLabelL); - static LabelDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static LabelDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); LabelStmt *getStmt() const { return TheStmt; } void setStmt(LabelStmt *T) { TheStmt = T; } @@ -581,7 +581,7 @@ public: IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested); - static NamespaceDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static NamespaceDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -1146,7 +1146,7 @@ public: const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S); - static VarDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static VarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -1728,7 +1728,7 @@ public: static ImplicitParamDecl *Create(ASTContext &C, QualType T, ImplicitParamKind ParamKind); - static ImplicitParamDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ImplicitParamDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType Type, @@ -1782,7 +1782,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg); - static ParmVarDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ParmVarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -2178,7 +2178,7 @@ public: bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause); - static FunctionDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); @@ -3136,7 +3136,7 @@ public: TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle); - static FieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Returns the index of this field within its record, /// as appropriate for passing to ASTRecordLayout::getFieldOffset. @@ -3311,7 +3311,7 @@ public: SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, const llvm::APSInt &V); - static EnumConstantDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static EnumConstantDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); const Expr *getInitExpr() const { return (const Expr*) Init; } Expr *getInitExpr() { return (Expr*) Init; } @@ -3357,7 +3357,7 @@ public: QualType T, llvm::MutableArrayRef CH); - static IndirectFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static IndirectFieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using chain_iterator = ArrayRef::const_iterator; @@ -3542,7 +3542,7 @@ public: static TypedefDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypedefDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TypedefDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3567,7 +3567,7 @@ public: static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypeAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TypeAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3977,7 +3977,7 @@ public: IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed); - static EnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static EnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Overrides to provide correct range when there's an enum-base specifier /// with forward declarations. @@ -4182,7 +4182,7 @@ public: static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr); - static RecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); + static RecordDecl *CreateDeserialized(const ASTContext &C, GlobalDeclID ID); RecordDecl *getPreviousDecl() { return cast_or_null( @@ -4433,7 +4433,7 @@ public: StringLiteral *Str, SourceLocation AsmLoc, SourceLocation RParenLoc); - static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getAsmLoc() const { return getLocation(); } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -4469,7 +4469,7 @@ class TopLevelStmtDecl : public Decl, public DeclContext { public: static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement); - static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; Stmt *getStmt() { return Statement; } @@ -4563,7 +4563,7 @@ protected: public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static BlockDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static BlockDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getCaretLocation() const { return getLocation(); } @@ -4717,7 +4717,7 @@ public: static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); - static CapturedDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static CapturedDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumParams); Stmt *getBody() const override; @@ -4851,7 +4851,7 @@ public: SourceLocation EndLoc); /// Create a new, deserialized module import declaration. - static ImportDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static ImportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumLocations); /// Retrieve the module that was imported by the import declaration. @@ -4892,7 +4892,7 @@ private: public: static ExportDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc); - static ExportDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ExportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getExportLoc() const { return getLocation(); } SourceLocation getRBraceLoc() const { return RBraceLoc; } @@ -4931,7 +4931,7 @@ class EmptyDecl : public Decl { public: static EmptyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static EmptyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static EmptyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Empty; } @@ -4957,7 +4957,7 @@ public: bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); - static HLSLBufferDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(getLocStart(), RBraceLoc); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 474e51c1df6d..e43e812cd945 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -359,7 +359,7 @@ protected: /// \param Ctx The context in which we will allocate memory. /// \param ID The global ID of the deserialized declaration. /// \param Extra The amount of extra space to allocate after the object. - void *operator new(std::size_t Size, const ASTContext &Ctx, DeclID ID, + void *operator new(std::size_t Size, const ASTContext &Ctx, GlobalDeclID ID, std::size_t Extra = 0); /// Allocate memory for a non-deserialized declaration. @@ -777,10 +777,10 @@ public: /// Retrieve the global declaration ID associated with this /// declaration, which specifies where this Decl was loaded from. - DeclID getGlobalID() const { + GlobalDeclID getGlobalID() const { if (isFromASTFile()) - return *((const DeclID *)this - 1); - return 0; + return (*((const GlobalDeclID *)this - 1)); + return GlobalDeclID(); } /// Retrieve the global ID of the module that owns this particular diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index a7644d2a19d2..fb52ac804849 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -120,7 +120,7 @@ public: return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); } - static AccessSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static AccessSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -579,7 +579,8 @@ public: TypeSourceInfo *Info, SourceLocation Loc, unsigned DependencyKind, bool IsGeneric, LambdaCaptureDefault CaptureDefault); - static CXXRecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); + static CXXRecordDecl *CreateDeserialized(const ASTContext &C, + GlobalDeclID ID); bool isDynamicClass() const { return data().Polymorphic || data().NumVBases != 0; @@ -1980,7 +1981,8 @@ public: CXXConstructorDecl *Ctor = nullptr, DeductionCandidate Kind = DeductionCandidate::Normal); - static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; } const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; } @@ -2035,7 +2037,8 @@ public: static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc); - static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2078,7 +2081,7 @@ public: ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static CXXMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); bool isStatic() const; bool isInstance() const { return !isStatic(); } @@ -2579,7 +2582,7 @@ public: friend class ASTDeclWriter; friend TrailingObjects; - static CXXConstructorDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, uint64_t AllocKind); static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, @@ -2822,7 +2825,7 @@ public: bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause = nullptr); - static CXXDestructorDecl *CreateDeserialized(ASTContext & C, DeclID ID); + static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg); @@ -2881,7 +2884,7 @@ public: bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXConversionDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static CXXConversionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ExplicitSpecifier getExplicitSpecifier() { return getCanonicalDecl()->ExplicitSpec; @@ -2948,7 +2951,7 @@ public: SourceLocation ExternLoc, SourceLocation LangLoc, LinkageSpecLanguageIDs Lang, bool HasBraces); - static LinkageSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static LinkageSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the language specified by this linkage specification. LinkageSpecLanguageIDs getLanguage() const { @@ -3096,7 +3099,7 @@ public: SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor); - static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(UsingLoc, getLocation()); @@ -3157,7 +3160,7 @@ public: SourceLocation IdentLoc, NamedDecl *Namespace); - static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3254,7 +3257,7 @@ public: LifetimeExtendedTemporaryDecl(Temp, EDec, Mangling); } static LifetimeExtendedTemporaryDecl *CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) LifetimeExtendedTemporaryDecl(EmptyShell{}); } @@ -3357,7 +3360,7 @@ public: UsingShadowDecl(UsingShadow, C, DC, Loc, Name, Introducer, Target); } - static UsingShadowDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingShadowDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3566,7 +3569,7 @@ public: const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword); - static UsingDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3645,7 +3648,7 @@ public: UsingDecl *Using, NamedDecl *Target, bool IsVirtual); static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); /// Override the UsingShadowDecl's getIntroducer, returning the UsingDecl that /// introduced this. @@ -3757,7 +3760,7 @@ public: SourceLocation UsingL, SourceLocation EnumL, SourceLocation NameL, TypeSourceInfo *EnumType); - static UsingEnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingEnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3830,7 +3833,7 @@ public: NamedDecl *InstantiatedFrom, ArrayRef UsingDecls); - static UsingPackDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static UsingPackDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions); SourceRange getSourceRange() const override LLVM_READONLY { @@ -3923,8 +3926,8 @@ public: NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc); - static UnresolvedUsingValueDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + static UnresolvedUsingValueDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -4014,8 +4017,8 @@ public: SourceLocation TargetNameLoc, DeclarationName TargetName, SourceLocation EllipsisLoc); - static UnresolvedUsingTypenameDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + static UnresolvedUsingTypenameDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); /// Retrieves the canonical declaration of this declaration. UnresolvedUsingTypenameDecl *getCanonicalDecl() override { @@ -4045,7 +4048,7 @@ public: SourceLocation Loc, DeclarationName Name); static UnresolvedUsingIfExistsDecl *CreateDeserialized(ASTContext &Ctx, - DeclID ID); + GlobalDeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingIfExists; } @@ -4073,7 +4076,7 @@ public: SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *Message, SourceLocation RParenLoc, bool Failed); - static StaticAssertDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static StaticAssertDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); } const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); } @@ -4120,7 +4123,7 @@ public: static BindingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id); - static BindingDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static BindingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Get the expression to which this declaration is bound. This may be null /// in two different cases: while parsing the initializer for the @@ -4189,7 +4192,7 @@ public: QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef Bindings); - static DecompositionDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static DecompositionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumBindings); ArrayRef bindings() const { @@ -4246,7 +4249,7 @@ public: SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL, IdentifierInfo *Getter, IdentifierInfo *Setter); - static MSPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static MSPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); static bool classof(const Decl *D) { return D->getKind() == MSProperty; } @@ -4300,7 +4303,7 @@ private: MSGuidDecl(DeclContext *DC, QualType T, Parts P); static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P); - static MSGuidDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static MSGuidDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); // Only ASTContext::getMSGuidDecl and deserialization create these. friend class ASTContext; @@ -4353,7 +4356,7 @@ class UnnamedGlobalConstantDecl : public ValueDecl, static UnnamedGlobalConstantDecl *Create(const ASTContext &C, QualType T, const APValue &APVal); static UnnamedGlobalConstantDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); // Only ASTContext::getUnnamedGlobalConstantDecl and deserialization create // these. diff --git a/clang/include/clang/AST/DeclFriend.h b/clang/include/clang/AST/DeclFriend.h index b56627a5337d..9789282f351a 100644 --- a/clang/include/clang/AST/DeclFriend.h +++ b/clang/include/clang/AST/DeclFriend.h @@ -112,7 +112,7 @@ public: Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, ArrayRef FriendTypeTPLists = std::nullopt); - static FriendDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static FriendDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned FriendTypeNumTPLists); /// If this friend declaration names an (untemplated but possibly diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h index e2c6dd65e86b..614ba06b6386 100644 --- a/clang/include/clang/AST/DeclID.h +++ b/clang/include/clang/AST/DeclID.h @@ -16,6 +16,7 @@ #ifndef LLVM_CLANG_AST_DECLID_H #define LLVM_CLANG_AST_DECLID_H +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/iterator.h" namespace clang { @@ -88,90 +89,139 @@ enum PredefinedDeclIDs { /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. const unsigned int NUM_PREDEF_DECL_IDS = 18; -/// An ID number that refers to a declaration in an AST file. -/// -/// The ID numbers of declarations are consecutive (in order of -/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. -/// At the start of a chain of precompiled headers, declaration ID 1 is -/// used for the translation unit declaration. -using DeclID = uint32_t; +/// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means +/// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the +/// LocalDeclID to the ModuleFile been writting is equal to the GlobalDeclID. +/// Outside the serializer, all the DeclID been used should be GlobalDeclID. +/// We can translate a LocalDeclID to the GlobalDeclID by +/// `ASTReader::getGlobalDeclID()`. -class LocalDeclID { +class DeclIDBase { public: - explicit LocalDeclID(DeclID ID) : ID(ID) {} + /// An ID number that refers to a declaration in an AST file. + /// + /// The ID numbers of declarations are consecutive (in order of + /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. + /// At the start of a chain of precompiled headers, declaration ID 1 is + /// used for the translation unit declaration. + /// + /// DeclID should only be used directly in serialization. All other users + /// should use LocalDeclID or GlobalDeclID. + using DeclID = uint32_t; + +protected: + DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {} + explicit DeclIDBase(DeclID ID) : ID(ID) {} +public: DeclID get() const { return ID; } -private: - DeclID ID; -}; + explicit operator DeclID() const { return ID; } -/// Wrapper class for DeclID. This is helpful to not mix the use of LocalDeclID -/// and GlobalDeclID to improve the type safety. -class GlobalDeclID { -public: - GlobalDeclID() : ID(PREDEF_DECL_NULL_ID) {} - explicit GlobalDeclID(DeclID ID) : ID(ID) {} + explicit operator PredefinedDeclIDs() const { return (PredefinedDeclIDs)ID; } - DeclID get() const { return ID; } + bool isValid() const { return ID != PREDEF_DECL_NULL_ID; } - explicit operator DeclID() const { return ID; } + bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; } - friend bool operator==(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID == RHS.ID; } - friend bool operator!=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID != RHS.ID; } - // We may sort the global decl ID. - friend bool operator<(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + // We may sort the decl ID. + friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID < RHS.ID; } - friend bool operator>(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator>(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID > RHS.ID; } - friend bool operator<=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator<=(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID <= RHS.ID; } - friend bool operator>=(const GlobalDeclID &LHS, const GlobalDeclID &RHS) { + friend bool operator>=(const DeclIDBase &LHS, const DeclIDBase &RHS) { return LHS.ID >= RHS.ID; } -private: +protected: DeclID ID; }; -/// A helper iterator adaptor to convert the iterators to `SmallVector` -/// to the iterators to `SmallVector`. -class GlobalDeclIDIterator - : public llvm::iterator_adaptor_base { +class LocalDeclID : public DeclIDBase { + using Base = DeclIDBase; + public: - GlobalDeclIDIterator() : iterator_adaptor_base(nullptr) {} + LocalDeclID() : Base() {} + LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {} + explicit LocalDeclID(DeclID ID) : Base(ID) {} + + LocalDeclID &operator++() { + ++ID; + return *this; + } + + LocalDeclID operator++(int) { + LocalDeclID Ret = *this; + ++(*this); + return Ret; + } +}; - GlobalDeclIDIterator(const DeclID *ID) : iterator_adaptor_base(ID) {} +class GlobalDeclID : public DeclIDBase { + using Base = DeclIDBase; - value_type operator*() const { return GlobalDeclID(*I); } +public: + GlobalDeclID() : Base() {} + explicit GlobalDeclID(DeclID ID) : Base(ID) {} - bool operator==(const GlobalDeclIDIterator &RHS) const { return I == RHS.I; } + // For DeclIDIterator to be able to convert a GlobalDeclID + // to a LocalDeclID. + explicit operator LocalDeclID() const { return LocalDeclID(this->ID); } }; /// A helper iterator adaptor to convert the iterators to -/// `SmallVector` to the iterators to `SmallVector`. +/// `SmallVector` to the iterators to `SmallVector`. +template class DeclIDIterator - : public llvm::iterator_adaptor_base { + : public llvm::iterator_adaptor_base, + const FromTy *, + std::forward_iterator_tag, ToTy> { public: - DeclIDIterator() : iterator_adaptor_base(nullptr) {} + DeclIDIterator() : DeclIDIterator::iterator_adaptor_base(nullptr) {} - DeclIDIterator(const GlobalDeclID *ID) : iterator_adaptor_base(ID) {} + DeclIDIterator(const FromTy *ID) + : DeclIDIterator::iterator_adaptor_base(ID) {} - value_type operator*() const { return DeclID(*I); } + ToTy operator*() const { return ToTy(*this->I); } - bool operator==(const DeclIDIterator &RHS) const { return I == RHS.I; } + bool operator==(const DeclIDIterator &RHS) const { return this->I == RHS.I; } }; } // namespace clang +namespace llvm { +template <> struct DenseMapInfo { + using GlobalDeclID = clang::GlobalDeclID; + using DeclID = GlobalDeclID::DeclID; + + static GlobalDeclID getEmptyKey() { + return GlobalDeclID(DenseMapInfo::getEmptyKey()); + } + + static GlobalDeclID getTombstoneKey() { + return GlobalDeclID(DenseMapInfo::getTombstoneKey()); + } + + static unsigned getHashValue(const GlobalDeclID &Key) { + return DenseMapInfo::getHashValue(Key.get()); + } + + static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) { + return L == R; + } +}; + +} // namespace llvm + #endif diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 7780afa6f1cf..d2cc61ca19f8 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -236,7 +236,7 @@ public: ObjCImplementationControl impControl = ObjCImplementationControl::None, bool HasRelatedResultType = false); - static ObjCMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ObjCMethodDecl *getCanonicalDecl() override; const ObjCMethodDecl *getCanonicalDecl() const { @@ -614,7 +614,8 @@ public: IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo); - static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, DeclID ID); + static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -789,7 +790,7 @@ public: TypeSourceInfo *TSI, PropertyControl propControl = None); - static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } @@ -1279,7 +1280,8 @@ public: ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc = SourceLocation(), bool isInternal = false); - static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, DeclID ID); + static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, + GlobalDeclID ID); /// Retrieve the type parameters of this class. /// @@ -1969,7 +1971,7 @@ public: TypeSourceInfo *TInfo, AccessControl ac, Expr *BW = nullptr, bool synthesized = false); - static ObjCIvarDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the class interface that this ivar is logically contained /// in; this is either the interface where the ivar was declared, or the @@ -2039,7 +2041,8 @@ public: SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW); - static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2142,7 +2145,7 @@ public: SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl); - static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); const ObjCProtocolList &getReferencedProtocols() const { assert(hasDefinition() && "No definition available!"); @@ -2361,7 +2364,7 @@ public: ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc = SourceLocation(), SourceLocation IvarRBraceLoc = SourceLocation()); - static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -2558,7 +2561,8 @@ public: Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc); - static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); ObjCCategoryDecl *getCategoryDecl() const; @@ -2640,7 +2644,8 @@ public: SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()); - static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); /// init_iterator - Iterates through the ivar initializer list. using init_iterator = CXXCtorInitializer **; @@ -2780,7 +2785,7 @@ public: ObjCInterfaceDecl* aliasedClass); static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } @@ -2851,7 +2856,8 @@ public: ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc); - static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h index c7ede7f2157f..e542c3c8e66b 100644 --- a/clang/include/clang/AST/DeclOpenMP.h +++ b/clang/include/clang/AST/DeclOpenMP.h @@ -59,7 +59,7 @@ protected: } template - static T *createEmptyDirective(const ASTContext &C, unsigned ID, + static T *createEmptyDirective(const ASTContext &C, GlobalDeclID ID, unsigned NumClauses, unsigned NumChildren, Params &&... P) { auto *Inst = new (C, ID, size(NumClauses, NumChildren)) @@ -133,7 +133,7 @@ public: SourceLocation L, ArrayRef VL); static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, - DeclID ID, unsigned N); + GlobalDeclID ID, unsigned N); typedef MutableArrayRef::iterator varlist_iterator; typedef ArrayRef::iterator varlist_const_iterator; @@ -214,7 +214,7 @@ public: QualType T, OMPDeclareReductionDecl *PrevDeclInScope); /// Create deserialized declare reduction node. static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); /// Get combiner expression of the declare reduction construct. Expr *getCombiner() { return Combiner; } @@ -318,8 +318,8 @@ public: ArrayRef Clauses, OMPDeclareMapperDecl *PrevDeclInScope); /// Creates deserialized declare mapper node. - static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, DeclID ID, - unsigned N); + static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; using clauselist_const_iterator = ArrayRef::iterator; @@ -397,7 +397,8 @@ public: IdentifierInfo *Id, QualType T, SourceLocation StartLoc); - static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -427,7 +428,7 @@ public: static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef CL); /// Create deserialized requires node. - static OMPRequiresDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static OMPRequiresDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; @@ -495,7 +496,7 @@ public: static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef VL, ArrayRef CL); - static OMPAllocateDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static OMPAllocateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NVars, unsigned NClauses); typedef MutableArrayRef::iterator varlist_iterator; diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 0c95459a6ab1..3ee03eebdb8c 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -797,7 +797,7 @@ protected: /// /// The first value in the array is the number of specializations/partial /// specializations that follow. - DeclID *LazySpecializations = nullptr; + GlobalDeclID *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -1087,7 +1087,8 @@ public: NamedDecl *Decl); /// Create an empty function template node. - static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1204,9 +1205,9 @@ public: bool Typename, bool ParameterPack, bool HasTypeConstraint = false, std::optional NumExpanded = std::nullopt); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - DeclID ID); + GlobalDeclID ID); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - DeclID ID, + GlobalDeclID ID, bool HasTypeConstraint); /// Whether this template type parameter was declared with @@ -1413,11 +1414,10 @@ public: QualType T, TypeSourceInfo *TInfo, ArrayRef ExpandedTypes, ArrayRef ExpandedTInfos); + static NonTypeTemplateParmDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID, - bool HasTypeConstraint); - static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID, + GlobalDeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint); @@ -1632,10 +1632,9 @@ public: ArrayRef Expansions); static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID); - static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID, - unsigned NumExpansions); + GlobalDeclID ID); + static TemplateTemplateParmDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions); using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; @@ -1857,8 +1856,8 @@ public: ClassTemplateDecl *SpecializedTemplate, ArrayRef Args, ClassTemplateSpecializationDecl *PrevDecl); - static ClassTemplateSpecializationDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2110,7 +2109,7 @@ public: ClassTemplatePartialSpecializationDecl *PrevDecl); static ClassTemplatePartialSpecializationDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + CreateDeserialized(ASTContext &C, GlobalDeclID ID); ClassTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -2306,7 +2305,7 @@ public: NamedDecl *Decl); /// Create an empty class template node. - static ClassTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ClassTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -2472,7 +2471,7 @@ public: MutableArrayRef Params, FriendUnion Friend, SourceLocation FriendLoc); - static FriendTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// If this friend declaration names a templated type (or /// a dependent member type of a templated type), return that @@ -2573,7 +2572,8 @@ public: NamedDecl *Decl); /// Create an empty alias template node. - static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2670,7 +2670,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args); static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2900,8 +2900,8 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args, const TemplateArgumentListInfo &ArgInfos); - static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + static VarTemplatePartialSpecializationDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID); VarTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -3078,7 +3078,7 @@ public: VarDecl *Decl); /// Create an empty variable template node. - static VarTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static VarTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -3183,7 +3183,7 @@ public: SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr); - static ConceptDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ConceptDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); Expr *getConstraintExpr() const { return ConstraintExpr; @@ -3232,7 +3232,7 @@ public: Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef ConvertedArgs); static ImplicitConceptSpecializationDecl * - CreateDeserialized(const ASTContext &C, DeclID ID, + CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs); ArrayRef getTemplateArguments() const { @@ -3275,7 +3275,7 @@ private: static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T, const APValue &V); static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); /// Only ASTContext::getTemplateParamObjectDecl and deserialization /// create these. diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index d0ee8ce6365a..385c32edbae0 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -99,7 +99,7 @@ public: /// passes back decl sets as VisibleDeclaration objects. /// /// The default implementation of this method is a no-op. - virtual Decl *GetExternalDecl(DeclID ID); + virtual Decl *GetExternalDecl(GlobalDeclID ID); /// Resolve a selector ID into a selector. /// @@ -375,7 +375,7 @@ public: if (isOffset()) { assert(Source && "Cannot deserialize a lazy pointer without an AST source"); - Ptr = reinterpret_cast((Source->*Get)(Ptr >> 1)); + Ptr = reinterpret_cast((Source->*Get)(OffsT(Ptr >> 1))); } return reinterpret_cast(Ptr); } @@ -579,7 +579,7 @@ using LazyDeclStmtPtr = /// A lazy pointer to a declaration. using LazyDeclPtr = - LazyOffsetPtr; + LazyOffsetPtr; /// A lazy pointer to a set of CXXCtorInitializers. using LazyCXXCtorInitializersPtr = diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 163e87cd3df3..080844893c13 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -241,7 +241,7 @@ private: /// A list of the serialization ID numbers for each of the top-level /// declarations parsed within the precompiled preamble. - std::vector TopLevelDeclsInPreamble; + std::vector TopLevelDeclsInPreamble; /// Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults : 1; diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h b/clang/include/clang/Frontend/MultiplexConsumer.h index 6a82c0dd8cec..f29c8e92fded 100644 --- a/clang/include/clang/Frontend/MultiplexConsumer.h +++ b/clang/include/clang/Frontend/MultiplexConsumer.h @@ -35,7 +35,7 @@ public: void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; void MacroRead(serialization::MacroID ID, MacroInfo *MI) override; void TypeRead(serialization::TypeIdx Idx, QualType T) override; - void DeclRead(DeclID ID, const Decl *D) override; + void DeclRead(GlobalDeclID ID, const Decl *D) override; void SelectorRead(serialization::SelectorID iD, Selector Sel) override; void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD) override; diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index da3204863a41..238fb398b7d1 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -65,7 +65,7 @@ public: /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. - Decl *GetExternalDecl(DeclID ID) override; + Decl *GetExternalDecl(GlobalDeclID ID) override; /// Complete the redeclaration chain if it's been extended since the /// previous generation of the AST source. diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 42e09a2bf634..186c3b722ced 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -60,6 +60,10 @@ const unsigned VERSION_MINOR = 1; /// and start at 1. 0 is reserved for NULL. using IdentifierID = uint32_t; +/// An ID number that refers to a declaration in an AST file. See the comments +/// in DeclIDBase for details. +using DeclID = DeclIDBase::DeclID; + /// An ID number that refers to a type in an AST file. /// /// The ID of a type is partitioned into two parts: the lower @@ -1979,7 +1983,7 @@ enum CleanupObjectKind { COK_Block, COK_CompoundLiteral }; /// Describes the categories of an Objective-C class. struct ObjCCategoriesInfo { // The ID of the definition - DeclID DefinitionID; + LocalDeclID DefinitionID; // Offset into the array of category lists. unsigned Offset; @@ -2078,27 +2082,6 @@ template <> struct DenseMapInfo { } }; -template <> struct DenseMapInfo { - using DeclID = clang::DeclID; - using GlobalDeclID = clang::GlobalDeclID; - - static GlobalDeclID getEmptyKey() { - return GlobalDeclID(DenseMapInfo::getEmptyKey()); - } - - static GlobalDeclID getTombstoneKey() { - return GlobalDeclID(DenseMapInfo::getTombstoneKey()); - } - - static unsigned getHashValue(const GlobalDeclID &Key) { - return DenseMapInfo::getHashValue(Key.get()); - } - - static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) { - return L == R; - } -}; - } // namespace llvm #endif // LLVM_CLANG_SERIALIZATION_ASTBITCODES_H diff --git a/clang/include/clang/Serialization/ASTDeserializationListener.h b/clang/include/clang/Serialization/ASTDeserializationListener.h index bb039558f7f7..3ab7f1a91843 100644 --- a/clang/include/clang/Serialization/ASTDeserializationListener.h +++ b/clang/include/clang/Serialization/ASTDeserializationListener.h @@ -44,7 +44,7 @@ public: /// unqualified. virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { } /// A decl was deserialized from the AST file. - virtual void DeclRead(DeclID ID, const Decl *D) {} + virtual void DeclRead(GlobalDeclID ID, const Decl *D) {} /// A selector was read from the AST file. virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {} /// A macro definition was read from the AST file. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 65e2bcb990c3..64f1ebc117b3 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -603,7 +603,8 @@ private: /// Decl::Kind, DeclID pairs. using unalighed_decl_id_t = llvm::support::detail::packed_endian_specific_integral< - DeclID, llvm::endianness::native, llvm::support::unaligned>; + serialization::DeclID, llvm::endianness::native, + llvm::support::unaligned>; using LexicalContents = ArrayRef; /// Map from a DeclContext to its lexical contents. @@ -1918,7 +1919,7 @@ public: /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. Decl *GetDecl(GlobalDeclID ID); - Decl *GetExternalDecl(DeclID ID) override; + Decl *GetExternalDecl(GlobalDeclID ID) override; /// Resolve a declaration ID into a declaration. Return 0 if it's not /// been loaded yet. @@ -1941,7 +1942,8 @@ public: /// /// \returns the global ID of the given declaration as known in the given /// module file. - DeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M, GlobalDeclID GlobalID); + LocalDeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + GlobalDeclID GlobalID); /// Reads a declaration ID from the given position in a record in the /// given module. diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index d01b31549248..6c45b7348b85 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -212,10 +212,10 @@ private: llvm::SmallVector DelayedNamespace; /// The first ID number we can use for our own declarations. - DeclID FirstDeclID = clang::NUM_PREDEF_DECL_IDS; + LocalDeclID FirstDeclID = LocalDeclID(clang::NUM_PREDEF_DECL_IDS); /// The decl ID that will be assigned to the next new decl. - DeclID NextDeclID = FirstDeclID; + LocalDeclID NextDeclID = FirstDeclID; /// Map that provides the ID numbers of each declaration within /// the output stream, as well as those deserialized from a chained PCH. @@ -223,7 +223,7 @@ private: /// The ID numbers of declarations are consecutive (in order of /// discovery) and start at 2. 1 is reserved for the translation /// unit, while 0 is reserved for NULL. - llvm::DenseMap DeclIDs; + llvm::DenseMap DeclIDs; /// Offset of each declaration in the bitstream, indexed by /// the declaration's ID. @@ -233,8 +233,8 @@ private: /// are relative to this value. uint64_t DeclTypesBlockStartOffset = 0; - /// Sorted (by file offset) vector of pairs of file offset/DeclID. - using LocDeclIDsTy = SmallVector, 64>; + /// Sorted (by file offset) vector of pairs of file offset/LocalDeclID. + using LocDeclIDsTy = SmallVector, 64>; struct DeclIDInFileInfo { LocDeclIDsTy DeclIDs; @@ -249,7 +249,7 @@ private: /// that it contains. FileDeclIDsTy FileDeclIDs; - void associateDeclWithFile(const Decl *D, DeclID); + void associateDeclWithFile(const Decl *D, LocalDeclID); /// The first ID number we can use for our own types. serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS; @@ -420,8 +420,8 @@ private: /// headers. The declarations themselves are stored as declaration /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS /// record. - SmallVector EagerlyDeserializedDecls; - SmallVector ModularCodegenDecls; + RecordData EagerlyDeserializedDecls; + RecordData ModularCodegenDecls; /// DeclContexts that have received extensions since their serialized /// form. @@ -707,7 +707,8 @@ public: if (D->isFromASTFile()) return false; auto I = DeclIDs.find(D); - return (I == DeclIDs.end() || I->second >= clang::NUM_PREDEF_DECL_IDS); + return (I == DeclIDs.end() || + I->second.get() >= clang::NUM_PREDEF_DECL_IDS); }; /// Emit a reference to a declaration. @@ -715,12 +716,13 @@ public: // Emit a reference to a declaration if the declaration was emitted. void AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record); - /// Force a declaration to be emitted and get its ID. - DeclID GetDeclRef(const Decl *D); + /// Force a declaration to be emitted and get its local ID to the module file + /// been writing. + LocalDeclID GetDeclRef(const Decl *D); - /// Determine the declaration ID of an already-emitted + /// Determine the local declaration ID of an already-emitted /// declaration. - DeclID getDeclID(const Decl *D); + LocalDeclID getDeclID(const Decl *D); /// Whether or not the declaration got emitted. If not, it wouldn't be /// emitted. diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 1f7222655876..25f644e76edb 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -459,10 +459,10 @@ public: const DeclOffset *DeclOffsets = nullptr; /// Base declaration ID for declarations local to this module. - DeclID BaseDeclID = 0; + serialization::DeclID BaseDeclID = 0; /// Remapping table for declaration IDs in this module. - ContinuousRangeMap DeclRemap; + ContinuousRangeMap DeclRemap; /// Mapping from the module files that this module file depends on /// to the base declaration ID for that module as it is understood within this @@ -471,7 +471,7 @@ public: /// This is effectively a reverse global-to-local mapping for declaration /// IDs, so that we can interpret a true global ID (for this translation unit) /// as a local ID (for this module file). - llvm::DenseMap GlobalToLocalDeclIDs; + llvm::DenseMap GlobalToLocalDeclIDs; /// Array of file-level DeclIDs sorted by file. const LocalDeclID *FileSortedDecls = nullptr; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a7386f755ca0..475b47afa639 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1083,7 +1083,8 @@ void ASTContext::addModuleInitializer(Module *M, Decl *D) { Inits->Initializers.push_back(D); } -void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef IDs) { +void ASTContext::addLazyModuleInitializers(Module *M, + ArrayRef IDs) { auto *&Inits = ModuleInitializers[M]; if (!Inits) Inits = new (*this) PerModuleInitializers; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index f452902110c7..e7e95c16b697 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2151,7 +2151,7 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartL, return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S); } -VarDecl *VarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +VarDecl *VarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None); @@ -2929,7 +2929,7 @@ QualType ParmVarDecl::getOriginalType() const { return T; } -ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None, nullptr); @@ -4553,7 +4553,7 @@ FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC, BW, Mutable, InitStyle); } -FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, nullptr, false, ICIS_NoInit); @@ -4863,7 +4863,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, return Enum; } -EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { EnumDecl *Enum = new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr, false, false, false); @@ -5025,7 +5025,8 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, return R; } -RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, DeclID ID) { +RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, + GlobalDeclID ID) { RecordDecl *R = new (C, ID) RecordDecl(Record, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -5297,7 +5298,7 @@ PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, } PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C, - DeclID ID, + GlobalDeclID ID, unsigned ArgSize) { return new (C, ID, additionalSizeToAlloc(ArgSize + 1)) PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown); @@ -5322,7 +5323,7 @@ PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC, } PragmaDetectMismatchDecl * -PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, DeclID ID, +PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize) { return new (C, ID, additionalSizeToAlloc(NameValueSize + 1)) PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0); @@ -5349,7 +5350,7 @@ LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL); } -LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation()); } @@ -5390,7 +5391,7 @@ ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, QualType Type, } ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other); } @@ -5408,7 +5409,7 @@ FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, return New; } -FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) FunctionDecl( Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -5418,7 +5419,7 @@ BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) BlockDecl(DC, L); } -BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) BlockDecl(nullptr, SourceLocation()); } @@ -5432,7 +5433,7 @@ CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC, CapturedDecl(DC, NumParams); } -CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, DeclID ID, +CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumParams) { return new (C, ID, additionalSizeToAlloc(NumParams)) CapturedDecl(nullptr, NumParams); @@ -5459,7 +5460,7 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, } EnumConstantDecl *EnumConstantDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) EnumConstantDecl(C, nullptr, SourceLocation(), nullptr, QualType(), nullptr, llvm::APSInt()); } @@ -5486,7 +5487,7 @@ IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) IndirectFieldDecl(C, nullptr, SourceLocation(), DeclarationName(), QualType(), std::nullopt); @@ -5547,7 +5548,7 @@ bool TypedefNameDecl::isTransparentTagSlow() const { return isTransparent; } -TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5560,7 +5561,8 @@ TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo); } -TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5591,7 +5593,7 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, } FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -5609,7 +5611,7 @@ TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) { } TopLevelStmtDecl *TopLevelStmtDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) TopLevelStmtDecl(/*DC=*/nullptr, SourceLocation(), /*S=*/nullptr); } @@ -5630,7 +5632,7 @@ EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) EmptyDecl(DC, L); } -EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) EmptyDecl(nullptr, SourceLocation()); } @@ -5663,7 +5665,8 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C, return Result; } -HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr, SourceLocation(), SourceLocation()); } @@ -5719,7 +5722,7 @@ ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC, return Import; } -ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, DeclID ID, +ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumLocations) { return new (C, ID, additionalSizeToAlloc(NumLocations)) ImportDecl(EmptyShell()); @@ -5752,6 +5755,6 @@ ExportDecl *ExportDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) ExportDecl(DC, ExportLoc); } -ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ExportDecl(nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index a2d88cf7a6a1..c33babf8d1df 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -70,8 +70,8 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const { #define ABSTRACT_DECL(DECL) #include "clang/AST/DeclNodes.inc" -void *Decl::operator new(std::size_t Size, const ASTContext &Context, DeclID ID, - std::size_t Extra) { +void *Decl::operator new(std::size_t Size, const ASTContext &Context, + GlobalDeclID ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. static_assert(sizeof(unsigned) * 2 >= alignof(Decl), @@ -85,7 +85,7 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, DeclID ID, PrefixPtr[0] = 0; // Store the global declaration ID in the second 4 bytes. - PrefixPtr[1] = ID; + PrefixPtr[1] = ID.get(); return Result; } diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index c525c3368ce2..75c441293d62 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -57,7 +57,8 @@ using namespace clang; void AccessSpecDecl::anchor() {} -AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) AccessSpecDecl(EmptyShell()); } @@ -68,7 +69,7 @@ void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const { for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I) I.setDecl(cast(Source->GetExternalDecl( - reinterpret_cast(I.getDecl()) >> 2))); + GlobalDeclID(reinterpret_cast(I.getDecl()) >> 2)))); Impl.Decls.setLazy(false); } @@ -161,7 +162,7 @@ CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, } CXXRecordDecl *CXXRecordDecl::CreateDeserialized(const ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { auto *R = new (C, ID) CXXRecordDecl(CXXRecord, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -2162,8 +2163,8 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( TInfo, EndLocation, Ctor, Kind); } -CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +CXXDeductionGuideDecl * +CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) CXXDeductionGuideDecl( C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), QualType(), nullptr, SourceLocation(), nullptr, @@ -2175,8 +2176,8 @@ RequiresExprBodyDecl *RequiresExprBodyDecl::Create( return new (C, DC) RequiresExprBodyDecl(C, DC, StartLoc); } -RequiresExprBodyDecl *RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +RequiresExprBodyDecl * +RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) RequiresExprBodyDecl(C, nullptr, SourceLocation()); } @@ -2281,7 +2282,8 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, isInline, ConstexprKind, EndLocation, TrailingRequiresClause); } -CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) CXXMethodDecl( CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, @@ -2699,7 +2701,7 @@ CXXConstructorDecl::CXXConstructorDecl( void CXXConstructorDecl::anchor() {} CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, - DeclID ID, + GlobalDeclID ID, uint64_t AllocKind) { bool hasTrailingExplicit = static_cast(AllocKind & TAKHasTailExplicit); bool isInheritingConstructor = @@ -2846,7 +2848,7 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const { void CXXDestructorDecl::anchor() {} CXXDestructorDecl *CXXDestructorDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) CXXDestructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -2878,7 +2880,7 @@ void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) { void CXXConversionDecl::anchor() {} CXXConversionDecl *CXXConversionDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) CXXConversionDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified, @@ -2923,7 +2925,8 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces); } -LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(), SourceLocation(), LinkageSpecLanguageIDs::C, false); @@ -2945,7 +2948,7 @@ UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, } UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), @@ -2984,7 +2987,8 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, PrevDecl, Nested); } -NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(), SourceLocation(), nullptr, nullptr, false); } @@ -3046,7 +3050,7 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, } NamespaceAliasDecl *NamespaceAliasDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, NestedNameSpecifierLoc(), @@ -3101,7 +3105,8 @@ UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty) : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()), redeclarable_base(C) {} -UsingShadowDecl *UsingShadowDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UsingShadowDecl *UsingShadowDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell()); } @@ -3124,7 +3129,7 @@ ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC, } ConstructorUsingShadowDecl * -ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell()); } @@ -3172,7 +3177,7 @@ UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL, return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename); } -UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) UsingDecl(nullptr, SourceLocation(), NestedNameSpecifierLoc(), DeclarationNameInfo(), false); @@ -3196,7 +3201,8 @@ UsingEnumDecl *UsingEnumDecl::Create(ASTContext &C, DeclContext *DC, UsingEnumDecl(DC, EnumType->getType()->getAsTagDecl()->getDeclName(), UL, EL, NL, EnumType); } -UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) UsingEnumDecl(nullptr, DeclarationName(), SourceLocation(), SourceLocation(), SourceLocation(), nullptr); @@ -3215,7 +3221,7 @@ UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls); } -UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, DeclID ID, +UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions) { size_t Extra = additionalSizeToAlloc(NumExpansions); auto *Result = @@ -3241,7 +3247,7 @@ UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingValueDecl * -UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(), SourceLocation(), NestedNameSpecifierLoc(), @@ -3271,7 +3277,8 @@ UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingTypenameDecl * -UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) UnresolvedUsingTypenameDecl( nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), nullptr, SourceLocation()); @@ -3284,7 +3291,8 @@ UnresolvedUsingIfExistsDecl::Create(ASTContext &Ctx, DeclContext *DC, } UnresolvedUsingIfExistsDecl * -UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, DeclID ID) { +UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, + GlobalDeclID ID) { return new (Ctx, ID) UnresolvedUsingIfExistsDecl(nullptr, SourceLocation(), DeclarationName()); } @@ -3308,7 +3316,7 @@ StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, } StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), false); } @@ -3330,7 +3338,7 @@ BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) BindingDecl(DC, IdLoc, Id); } -BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); } @@ -3361,7 +3369,7 @@ DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, } DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C, - DeclID ID, + GlobalDeclID ID, unsigned NumBindings) { size_t Extra = additionalSizeToAlloc(NumBindings); auto *Result = new (C, ID, Extra) @@ -3399,7 +3407,8 @@ MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) MSPropertyDecl(DC, L, N, T, TInfo, StartL, Getter, Setter); } -MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(), DeclarationName(), QualType(), nullptr, SourceLocation(), nullptr, nullptr); @@ -3416,7 +3425,7 @@ MSGuidDecl *MSGuidDecl::Create(const ASTContext &C, QualType T, Parts P) { return new (C, DC) MSGuidDecl(DC, T, P); } -MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) MSGuidDecl(nullptr, QualType(), Parts()); } @@ -3526,7 +3535,7 @@ UnnamedGlobalConstantDecl::Create(const ASTContext &C, QualType T, } UnnamedGlobalConstantDecl * -UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) UnnamedGlobalConstantDecl(C, nullptr, QualType(), APValue()); } diff --git a/clang/lib/AST/DeclFriend.cpp b/clang/lib/AST/DeclFriend.cpp index f6d11e550b57..04b9b93699f3 100644 --- a/clang/lib/AST/DeclFriend.cpp +++ b/clang/lib/AST/DeclFriend.cpp @@ -62,7 +62,7 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, return FD; } -FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, DeclID ID, +FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned FriendTypeNumTPLists) { std::size_t Extra = additionalSizeToAlloc(FriendTypeNumTPLists); diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index f98ec6727e48..83062b0e6887 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -862,7 +862,8 @@ ObjCMethodDecl *ObjCMethodDecl::Create( isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); } -ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(), Selector(), QualType(), nullptr, nullptr); } @@ -1486,7 +1487,7 @@ ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc, } ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx, - DeclID ID) { + GlobalDeclID ID) { return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr, ObjCTypeParamVariance::Invariant, SourceLocation(), 0, SourceLocation(), @@ -1551,7 +1552,7 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create( } ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { auto *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), nullptr, false); @@ -1865,7 +1866,7 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, synthesized); } -ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, ObjCIvarDecl::None, nullptr, false); @@ -1914,7 +1915,7 @@ ObjCAtDefsFieldDecl } ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr); @@ -1949,7 +1950,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, } ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { ObjCProtocolDecl *Result = new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(), SourceLocation(), nullptr); @@ -2148,7 +2149,7 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create( } ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(), SourceLocation(), SourceLocation(), nullptr, nullptr, nullptr); @@ -2188,8 +2189,8 @@ ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create( atStartLoc, CategoryNameLoc); } -ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +ObjCCategoryImplDecl * +ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation(), SourceLocation()); @@ -2296,7 +2297,7 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, } ObjCImplementationDecl * -ObjCImplementationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ObjCImplementationDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -2339,7 +2340,7 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, } ObjCCompatibleAliasDecl * -ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(), nullptr, nullptr); } @@ -2360,7 +2361,7 @@ ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr, SourceLocation(), SourceLocation(), QualType(), nullptr, None); @@ -2392,8 +2393,8 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, ivarLoc); } -ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +ObjCPropertyImplDecl * +ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, Dynamic, nullptr, SourceLocation()); diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp index 9f1d2bd41235..81ca48e60942 100644 --- a/clang/lib/AST/DeclOpenMP.cpp +++ b/clang/lib/AST/DeclOpenMP.cpp @@ -35,8 +35,9 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C, return D; } -OMPThreadPrivateDecl * -OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { +OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, + unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, 0, N); } @@ -62,7 +63,8 @@ OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC, return D; } -OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, DeclID ID, +OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned NVars, unsigned NClauses) { return OMPDeclarativeDirective::createEmptyDirective( @@ -88,7 +90,8 @@ OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC, L); } -OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, DeclID ID, +OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 0, SourceLocation()); @@ -116,7 +119,7 @@ OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create( } OMPDeclareReductionDecl * -OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) OMPDeclareReductionDecl( OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(), QualType(), /*PrevDeclInScope=*/nullptr); @@ -146,8 +149,9 @@ OMPDeclareMapperDecl *OMPDeclareMapperDecl::Create( C, DC, Clauses, 1, L, Name, T, VarName, PrevDeclInScope); } -OMPDeclareMapperDecl * -OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, DeclID ID, unsigned N) { +OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, + unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 1, SourceLocation(), DeclarationName(), QualType(), DeclarationName(), /*PrevDeclInScope=*/nullptr); @@ -177,7 +181,7 @@ OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC, } OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType(), /*TInfo=*/nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index ca998b502bee..d27a30e0c5fc 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -337,9 +337,10 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); if (CommonBasePtr->LazySpecializations) { ASTContext &Context = getASTContext(); - DeclID *Specs = CommonBasePtr->LazySpecializations; + GlobalDeclID *Specs = CommonBasePtr->LazySpecializations; CommonBasePtr->LazySpecializations = nullptr; - for (uint32_t I = 0, N = *Specs++; I != N; ++I) + unsigned SpecSize = (*Specs++).get(); + for (unsigned I = 0; I != SpecSize; ++I) (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); } } @@ -417,8 +418,8 @@ FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, return TD; } -FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +FunctionTemplateDecl * +FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -503,7 +504,7 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC, } ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -652,14 +653,14 @@ TemplateTypeParmDecl *TemplateTypeParmDecl::Create( } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, DeclID ID) { +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) { return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, false, false, std::nullopt); } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, DeclID ID, +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc(HasTypeConstraint ? 1 : 0)) @@ -759,7 +760,7 @@ NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc, @@ -770,7 +771,7 @@ NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint) { auto *NTTP = @@ -836,13 +837,13 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, false, nullptr, false, nullptr); } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, DeclID ID, +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions) { auto *TTP = new (C, ID, additionalSizeToAlloc(NumExpansions)) @@ -948,7 +949,8 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, } ClassTemplateSpecializationDecl * -ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { auto *Result = new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); Result->setMayHaveOutOfDateDef(false); @@ -1034,7 +1036,7 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, return TD; } -ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); @@ -1068,7 +1070,7 @@ ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( ImplicitConceptSpecializationDecl * ImplicitConceptSpecializationDecl::CreateDeserialized( - const ASTContext &C, DeclID ID, unsigned NumTemplateArgs) { + const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) { return new (C, ID, additionalSizeToAlloc(NumTemplateArgs)) ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); } @@ -1131,7 +1133,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, ClassTemplatePartialSpecializationDecl * ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); Result->setMayHaveOutOfDateDef(false); return Result; @@ -1158,7 +1160,7 @@ FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, } FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) FriendTemplateDecl(EmptyShell()); } @@ -1177,8 +1179,8 @@ TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, return TD; } -TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { +TypeAliasTemplateDecl * +TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1215,7 +1217,8 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, return TD; } -VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1337,7 +1340,8 @@ VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( } VarTemplateSpecializationDecl * -VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) VarTemplateSpecializationDecl(VarTemplateSpecialization, C); } @@ -1429,7 +1433,7 @@ VarTemplatePartialSpecializationDecl::Create( VarTemplatePartialSpecializationDecl * VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) VarTemplatePartialSpecializationDecl(C); } @@ -1543,7 +1547,7 @@ TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C, } TemplateParamObjectDecl * -TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, DeclID ID) { +TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue()); C.addDestruction(&TPOD->Value); return TPOD; diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index 26ded22bf329..e96a47496851 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -68,7 +68,7 @@ bool ExternalASTSource::layoutRecordType( return false; } -Decl *ExternalASTSource::GetExternalDecl(DeclID ID) { return nullptr; } +Decl *ExternalASTSource::GetExternalDecl(GlobalDeclID ID) { return nullptr; } Selector ExternalASTSource::GetExternalSelector(uint32_t ID) { return Selector(); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 361331de145b..2f75313e8a4c 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1067,7 +1067,7 @@ public: std::vector takeTopLevelDecls() { return std::move(TopLevelDecls); } - std::vector takeTopLevelDeclIDs() { + std::vector takeTopLevelDeclIDs() { return std::move(TopLevelDeclIDs); } @@ -1101,7 +1101,7 @@ public: private: unsigned Hash = 0; std::vector TopLevelDecls; - std::vector TopLevelDeclIDs; + std::vector TopLevelDeclIDs; llvm::SmallVector PreambleDiags; }; @@ -1471,7 +1471,9 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() { for (const auto TopLevelDecl : TopLevelDeclsInPreamble) { // Resolve the declaration ID to an actual declaration, possibly // deserializing the declaration in the process. - if (Decl *D = Source.GetExternalDecl(TopLevelDecl)) + // + // FIMXE: We shouldn't convert a LocalDeclID to GlobalDeclID directly. + if (Decl *D = Source.GetExternalDecl(GlobalDeclID(TopLevelDecl.get()))) Resolved.push_back(D); } TopLevelDeclsInPreamble.clear(); diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 91ce16e5e795..a2af738a053e 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -80,7 +80,7 @@ public: if (Previous) Previous->TypeRead(Idx, T); } - void DeclRead(DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { if (Previous) Previous->DeclRead(ID, D); } @@ -102,7 +102,7 @@ public: bool DeletePrevious) : DelegatingDeserializationListener(Previous, DeletePrevious) {} - void DeclRead(DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { llvm::outs() << "PCH DECL: " << D->getDeclKindName(); if (const NamedDecl *ND = dyn_cast(D)) { llvm::outs() << " - "; @@ -128,7 +128,7 @@ public: : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx), NamesToCheck(NamesToCheck) {} - void DeclRead(DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { if (const NamedDecl *ND = dyn_cast(D)) if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { unsigned DiagID diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index 9e885c8dc0f6..c74bfd86195f 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -52,7 +52,8 @@ void MultiplexASTDeserializationListener::TypeRead( Listeners[i]->TypeRead(Idx, T); } -void MultiplexASTDeserializationListener::DeclRead(DeclID ID, const Decl *D) { +void MultiplexASTDeserializationListener::DeclRead(GlobalDeclID ID, + const Decl *D) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->DeclRead(ID, D); } diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index e48c72498389..79e656eb4b7e 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -46,7 +46,7 @@ void MultiplexExternalSemaSource::AddSource(ExternalSemaSource *Source) { // ExternalASTSource. //===----------------------------------------------------------------------===// -Decl *MultiplexExternalSemaSource::GetExternalDecl(DeclID ID) { +Decl *MultiplexExternalSemaSource::GetExternalDecl(GlobalDeclID ID) { for(size_t i = 0; i < Sources.size(); ++i) if (Decl *Result = Sources[i]->GetExternalDecl(ID)) return Result; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index df9984d537bf..c99d6ed1c36c 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -5101,8 +5101,9 @@ void ASTReader::InitializeContext() { // If there's a listener, notify them that we "read" the translation unit. if (DeserializationListener) - DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, - Context.getTranslationUnitDecl()); + DeserializationListener->DeclRead( + GlobalDeclID(PREDEF_DECL_TRANSLATION_UNIT_ID), + Context.getTranslationUnitDecl()); // FIXME: Find a better way to deal with collisions between these // built-in types. Right now, we just ignore the problem. @@ -6010,9 +6011,9 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F, case SUBMODULE_INITIALIZERS: { if (!ContextObj) break; - SmallVector Inits; + SmallVector Inits; for (auto &ID : Record) - Inits.push_back(getGlobalDeclID(F, LocalDeclID(ID)).get()); + Inits.push_back(getGlobalDeclID(F, LocalDeclID(ID))); ContextObj->addLazyModuleInitializers(CurrentModule, Inits); break; } @@ -7517,9 +7518,7 @@ ASTRecordReader::readASTTemplateArgumentListInfo() { return ASTTemplateArgumentListInfo::Create(getContext(), Result); } -Decl *ASTReader::GetExternalDecl(DeclID ID) { - return GetDecl(GlobalDeclID(ID)); -} +Decl *ASTReader::GetExternalDecl(GlobalDeclID ID) { return GetDecl(ID); } void ASTReader::CompleteRedeclChain(const Decl *D) { if (NumCurrentElementsDeserializing) { @@ -7767,7 +7766,7 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { assert(ContextObj && "reading decl with no AST context"); if (ID.get() < NUM_PREDEF_DECL_IDS) { - Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID.get()); + Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID); if (D) { // Track that we have merged the declaration with ID \p ID into the // pre-existing predefined declaration \p D. @@ -7804,17 +7803,17 @@ Decl *ASTReader::GetDecl(GlobalDeclID ID) { if (!DeclsLoaded[Index]) { ReadDeclRecord(ID); if (DeserializationListener) - DeserializationListener->DeclRead(ID.get(), DeclsLoaded[Index]); + DeserializationListener->DeclRead(ID, DeclsLoaded[Index]); } return DeclsLoaded[Index]; } -DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, - GlobalDeclID GlobalID) { +LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + GlobalDeclID GlobalID) { DeclID ID = GlobalID.get(); if (ID < NUM_PREDEF_DECL_IDS) - return ID; + return LocalDeclID(ID); GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID); assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); @@ -7823,9 +7822,9 @@ DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, llvm::DenseMap::iterator Pos = M.GlobalToLocalDeclIDs.find(Owner); if (Pos == M.GlobalToLocalDeclIDs.end()) - return 0; + return LocalDeclID(); - return ID - Owner->BaseDeclID + Pos->second; + return LocalDeclID(ID - Owner->BaseDeclID + Pos->second); } GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordData &Record, @@ -7992,6 +7991,7 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, // Load the list of declarations. SmallVector Decls; llvm::SmallPtrSet Found; + for (GlobalDeclID ID : It->second.Table.find(Name)) { NamedDecl *ND = cast(GetDecl(ID)); if (ND->getDeclName() == Name && Found.insert(ND).second) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 9707eed701e9..744f11de88c2 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -273,17 +273,15 @@ namespace clang { auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations; if (auto &Old = LazySpecializations) { - IDs.insert(IDs.end(), GlobalDeclIDIterator(Old + 1), - GlobalDeclIDIterator(Old + 1 + Old[0])); + IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0].get()); llvm::sort(IDs); IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); } - auto *Result = new (C) DeclID[1 + IDs.size()]; - *Result = IDs.size(); + auto *Result = new (C) GlobalDeclID[1 + IDs.size()]; + *Result = GlobalDeclID(IDs.size()); - std::copy(DeclIDIterator(IDs.begin()), DeclIDIterator(IDs.end()), - Result + 1); + std::copy(IDs.begin(), IDs.end(), Result + 1); LazySpecializations = Result; } @@ -558,7 +556,7 @@ void ASTDeclReader::Visit(Decl *D) { // If this is a tag declaration with a typedef name for linkage, it's safe // to load that typedef now. - if (NamedDeclForTagDecl != GlobalDeclID()) + if (NamedDeclForTagDecl.isValid()) cast(D)->TypedefNameDeclOrQualifier = cast(Reader.GetDecl(NamedDeclForTagDecl)); } else if (auto *ID = dyn_cast(D)) { @@ -603,7 +601,7 @@ void ASTDeclReader::VisitDecl(Decl *D) { GlobalDeclID SemaDCIDForTemplateParmDecl = readDeclID(); GlobalDeclID LexicalDCIDForTemplateParmDecl = HasStandaloneLexicalDC ? readDeclID() : GlobalDeclID(); - if (LexicalDCIDForTemplateParmDecl == GlobalDeclID()) + if (LexicalDCIDForTemplateParmDecl.isInvalid()) LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl; Reader.addPendingDeclContextInfo(D, SemaDCIDForTemplateParmDecl, @@ -1860,7 +1858,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { mergeRedeclarable(D, Redecl); - if (AnonNamespace != GlobalDeclID()) { + if (AnonNamespace.isValid()) { // Each module has its own anonymous namespace, which is disjoint from // any other module's anonymous namespaces, so don't attach the anonymous // namespace at all. @@ -2792,9 +2790,9 @@ ASTDeclReader::VisitRedeclarable(Redeclarable *D) { uint64_t RedeclOffset = 0; - // 0 indicates that this declaration was the only declaration of its entity, - // and is used for space optimization. - if (FirstDeclID == GlobalDeclID()) { + // invalid FirstDeclID indicates that this declaration was the only + // declaration of its entity, and is used for space optimization. + if (FirstDeclID.isInvalid()) { FirstDeclID = ThisDeclID; IsKeyDecl = true; IsFirstLocalDecl = true; @@ -3829,240 +3827,232 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { Twine("ASTReader::readDeclRecord failed reading decl code: ") + toString(MaybeDeclCode.takeError())); - DeclID RawGlobalID = ID.get(); switch ((DeclCode)MaybeDeclCode.get()) { case DECL_CONTEXT_LEXICAL: case DECL_CONTEXT_VISIBLE: llvm_unreachable("Record cannot be de-serialized with readDeclRecord"); case DECL_TYPEDEF: - D = TypedefDecl::CreateDeserialized(Context, RawGlobalID); + D = TypedefDecl::CreateDeserialized(Context, ID); break; case DECL_TYPEALIAS: - D = TypeAliasDecl::CreateDeserialized(Context, RawGlobalID); + D = TypeAliasDecl::CreateDeserialized(Context, ID); break; case DECL_ENUM: - D = EnumDecl::CreateDeserialized(Context, RawGlobalID); + D = EnumDecl::CreateDeserialized(Context, ID); break; case DECL_RECORD: - D = RecordDecl::CreateDeserialized(Context, RawGlobalID); + D = RecordDecl::CreateDeserialized(Context, ID); break; case DECL_ENUM_CONSTANT: - D = EnumConstantDecl::CreateDeserialized(Context, RawGlobalID); + D = EnumConstantDecl::CreateDeserialized(Context, ID); break; case DECL_FUNCTION: - D = FunctionDecl::CreateDeserialized(Context, RawGlobalID); + D = FunctionDecl::CreateDeserialized(Context, ID); break; case DECL_LINKAGE_SPEC: - D = LinkageSpecDecl::CreateDeserialized(Context, RawGlobalID); + D = LinkageSpecDecl::CreateDeserialized(Context, ID); break; case DECL_EXPORT: - D = ExportDecl::CreateDeserialized(Context, RawGlobalID); + D = ExportDecl::CreateDeserialized(Context, ID); break; case DECL_LABEL: - D = LabelDecl::CreateDeserialized(Context, RawGlobalID); + D = LabelDecl::CreateDeserialized(Context, ID); break; case DECL_NAMESPACE: - D = NamespaceDecl::CreateDeserialized(Context, RawGlobalID); + D = NamespaceDecl::CreateDeserialized(Context, ID); break; case DECL_NAMESPACE_ALIAS: - D = NamespaceAliasDecl::CreateDeserialized(Context, RawGlobalID); + D = NamespaceAliasDecl::CreateDeserialized(Context, ID); break; case DECL_USING: - D = UsingDecl::CreateDeserialized(Context, RawGlobalID); + D = UsingDecl::CreateDeserialized(Context, ID); break; case DECL_USING_PACK: - D = UsingPackDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = UsingPackDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_USING_SHADOW: - D = UsingShadowDecl::CreateDeserialized(Context, RawGlobalID); + D = UsingShadowDecl::CreateDeserialized(Context, ID); break; case DECL_USING_ENUM: - D = UsingEnumDecl::CreateDeserialized(Context, RawGlobalID); + D = UsingEnumDecl::CreateDeserialized(Context, ID); break; case DECL_CONSTRUCTOR_USING_SHADOW: - D = ConstructorUsingShadowDecl::CreateDeserialized(Context, RawGlobalID); + D = ConstructorUsingShadowDecl::CreateDeserialized(Context, ID); break; case DECL_USING_DIRECTIVE: - D = UsingDirectiveDecl::CreateDeserialized(Context, RawGlobalID); + D = UsingDirectiveDecl::CreateDeserialized(Context, ID); break; case DECL_UNRESOLVED_USING_VALUE: - D = UnresolvedUsingValueDecl::CreateDeserialized(Context, RawGlobalID); + D = UnresolvedUsingValueDecl::CreateDeserialized(Context, ID); break; case DECL_UNRESOLVED_USING_TYPENAME: - D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, RawGlobalID); + D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, ID); break; case DECL_UNRESOLVED_USING_IF_EXISTS: - D = UnresolvedUsingIfExistsDecl::CreateDeserialized(Context, RawGlobalID); + D = UnresolvedUsingIfExistsDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_RECORD: - D = CXXRecordDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXRecordDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_DEDUCTION_GUIDE: - D = CXXDeductionGuideDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXDeductionGuideDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_METHOD: - D = CXXMethodDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXMethodDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_CONSTRUCTOR: - D = CXXConstructorDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = CXXConstructorDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_CXX_DESTRUCTOR: - D = CXXDestructorDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXDestructorDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_CONVERSION: - D = CXXConversionDecl::CreateDeserialized(Context, RawGlobalID); + D = CXXConversionDecl::CreateDeserialized(Context, ID); break; case DECL_ACCESS_SPEC: - D = AccessSpecDecl::CreateDeserialized(Context, RawGlobalID); + D = AccessSpecDecl::CreateDeserialized(Context, ID); break; case DECL_FRIEND: - D = FriendDecl::CreateDeserialized(Context, RawGlobalID, Record.readInt()); + D = FriendDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_FRIEND_TEMPLATE: - D = FriendTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = FriendTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_CLASS_TEMPLATE: - D = ClassTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = ClassTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_CLASS_TEMPLATE_SPECIALIZATION: - D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, - RawGlobalID); + D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, ID); break; case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION: - D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, - RawGlobalID); + D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); break; case DECL_VAR_TEMPLATE: - D = VarTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = VarTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_VAR_TEMPLATE_SPECIALIZATION: - D = VarTemplateSpecializationDecl::CreateDeserialized(Context, RawGlobalID); + D = VarTemplateSpecializationDecl::CreateDeserialized(Context, ID); break; case DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION: - D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, - RawGlobalID); + D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); break; case DECL_FUNCTION_TEMPLATE: - D = FunctionTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = FunctionTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_TEMPLATE_TYPE_PARM: { bool HasTypeConstraint = Record.readInt(); - D = TemplateTypeParmDecl::CreateDeserialized(Context, RawGlobalID, + D = TemplateTypeParmDecl::CreateDeserialized(Context, ID, HasTypeConstraint); break; } case DECL_NON_TYPE_TEMPLATE_PARM: { bool HasTypeConstraint = Record.readInt(); - D = NonTypeTemplateParmDecl::CreateDeserialized(Context, RawGlobalID, + D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, HasTypeConstraint); break; } case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: { bool HasTypeConstraint = Record.readInt(); D = NonTypeTemplateParmDecl::CreateDeserialized( - Context, RawGlobalID, Record.readInt(), HasTypeConstraint); + Context, ID, Record.readInt(), HasTypeConstraint); break; } case DECL_TEMPLATE_TEMPLATE_PARM: - D = TemplateTemplateParmDecl::CreateDeserialized(Context, RawGlobalID); + D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID); break; case DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK: - D = TemplateTemplateParmDecl::CreateDeserialized(Context, RawGlobalID, + D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_TYPE_ALIAS_TEMPLATE: - D = TypeAliasTemplateDecl::CreateDeserialized(Context, RawGlobalID); + D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID); break; case DECL_CONCEPT: - D = ConceptDecl::CreateDeserialized(Context, RawGlobalID); + D = ConceptDecl::CreateDeserialized(Context, ID); break; case DECL_REQUIRES_EXPR_BODY: - D = RequiresExprBodyDecl::CreateDeserialized(Context, RawGlobalID); + D = RequiresExprBodyDecl::CreateDeserialized(Context, ID); break; case DECL_STATIC_ASSERT: - D = StaticAssertDecl::CreateDeserialized(Context, RawGlobalID); + D = StaticAssertDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_METHOD: - D = ObjCMethodDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCMethodDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_INTERFACE: - D = ObjCInterfaceDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCInterfaceDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_IVAR: - D = ObjCIvarDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCIvarDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_PROTOCOL: - D = ObjCProtocolDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCProtocolDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_AT_DEFS_FIELD: - D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_CATEGORY: - D = ObjCCategoryDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCCategoryDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_CATEGORY_IMPL: - D = ObjCCategoryImplDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCCategoryImplDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_IMPLEMENTATION: - D = ObjCImplementationDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCImplementationDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_COMPATIBLE_ALIAS: - D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_PROPERTY: - D = ObjCPropertyDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCPropertyDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_PROPERTY_IMPL: - D = ObjCPropertyImplDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCPropertyImplDecl::CreateDeserialized(Context, ID); break; case DECL_FIELD: - D = FieldDecl::CreateDeserialized(Context, RawGlobalID); + D = FieldDecl::CreateDeserialized(Context, ID); break; case DECL_INDIRECTFIELD: - D = IndirectFieldDecl::CreateDeserialized(Context, RawGlobalID); + D = IndirectFieldDecl::CreateDeserialized(Context, ID); break; case DECL_VAR: - D = VarDecl::CreateDeserialized(Context, RawGlobalID); + D = VarDecl::CreateDeserialized(Context, ID); break; case DECL_IMPLICIT_PARAM: - D = ImplicitParamDecl::CreateDeserialized(Context, RawGlobalID); + D = ImplicitParamDecl::CreateDeserialized(Context, ID); break; case DECL_PARM_VAR: - D = ParmVarDecl::CreateDeserialized(Context, RawGlobalID); + D = ParmVarDecl::CreateDeserialized(Context, ID); break; case DECL_DECOMPOSITION: - D = DecompositionDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = DecompositionDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_BINDING: - D = BindingDecl::CreateDeserialized(Context, RawGlobalID); + D = BindingDecl::CreateDeserialized(Context, ID); break; case DECL_FILE_SCOPE_ASM: - D = FileScopeAsmDecl::CreateDeserialized(Context, RawGlobalID); + D = FileScopeAsmDecl::CreateDeserialized(Context, ID); break; case DECL_TOP_LEVEL_STMT_DECL: - D = TopLevelStmtDecl::CreateDeserialized(Context, RawGlobalID); + D = TopLevelStmtDecl::CreateDeserialized(Context, ID); break; case DECL_BLOCK: - D = BlockDecl::CreateDeserialized(Context, RawGlobalID); + D = BlockDecl::CreateDeserialized(Context, ID); break; case DECL_MS_PROPERTY: - D = MSPropertyDecl::CreateDeserialized(Context, RawGlobalID); + D = MSPropertyDecl::CreateDeserialized(Context, ID); break; case DECL_MS_GUID: - D = MSGuidDecl::CreateDeserialized(Context, RawGlobalID); + D = MSGuidDecl::CreateDeserialized(Context, ID); break; case DECL_UNNAMED_GLOBAL_CONSTANT: - D = UnnamedGlobalConstantDecl::CreateDeserialized(Context, RawGlobalID); + D = UnnamedGlobalConstantDecl::CreateDeserialized(Context, ID); break; case DECL_TEMPLATE_PARAM_OBJECT: - D = TemplateParamObjectDecl::CreateDeserialized(Context, RawGlobalID); + D = TemplateParamObjectDecl::CreateDeserialized(Context, ID); break; case DECL_CAPTURED: - D = CapturedDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = CapturedDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_CXX_BASE_SPECIFIERS: Error("attempt to read a C++ base-specifier record as a declaration"); @@ -4073,66 +4063,62 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { case DECL_IMPORT: // Note: last entry of the ImportDecl record is the number of stored source // locations. - D = ImportDecl::CreateDeserialized(Context, RawGlobalID, Record.back()); + D = ImportDecl::CreateDeserialized(Context, ID, Record.back()); break; case DECL_OMP_THREADPRIVATE: { Record.skipInts(1); unsigned NumChildren = Record.readInt(); Record.skipInts(1); - D = OMPThreadPrivateDecl::CreateDeserialized(Context, RawGlobalID, - NumChildren); + D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, NumChildren); break; } case DECL_OMP_ALLOCATE: { unsigned NumClauses = Record.readInt(); unsigned NumVars = Record.readInt(); Record.skipInts(1); - D = OMPAllocateDecl::CreateDeserialized(Context, RawGlobalID, NumVars, - NumClauses); + D = OMPAllocateDecl::CreateDeserialized(Context, ID, NumVars, NumClauses); break; } case DECL_OMP_REQUIRES: { unsigned NumClauses = Record.readInt(); Record.skipInts(2); - D = OMPRequiresDecl::CreateDeserialized(Context, RawGlobalID, NumClauses); + D = OMPRequiresDecl::CreateDeserialized(Context, ID, NumClauses); break; } case DECL_OMP_DECLARE_REDUCTION: - D = OMPDeclareReductionDecl::CreateDeserialized(Context, RawGlobalID); + D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID); break; case DECL_OMP_DECLARE_MAPPER: { unsigned NumClauses = Record.readInt(); Record.skipInts(2); - D = OMPDeclareMapperDecl::CreateDeserialized(Context, RawGlobalID, - NumClauses); + D = OMPDeclareMapperDecl::CreateDeserialized(Context, ID, NumClauses); break; } case DECL_OMP_CAPTUREDEXPR: - D = OMPCapturedExprDecl::CreateDeserialized(Context, RawGlobalID); + D = OMPCapturedExprDecl::CreateDeserialized(Context, ID); break; case DECL_PRAGMA_COMMENT: - D = PragmaCommentDecl::CreateDeserialized(Context, RawGlobalID, - Record.readInt()); + D = PragmaCommentDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_PRAGMA_DETECT_MISMATCH: - D = PragmaDetectMismatchDecl::CreateDeserialized(Context, RawGlobalID, + D = PragmaDetectMismatchDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_EMPTY: - D = EmptyDecl::CreateDeserialized(Context, RawGlobalID); + D = EmptyDecl::CreateDeserialized(Context, ID); break; case DECL_LIFETIME_EXTENDED_TEMPORARY: - D = LifetimeExtendedTemporaryDecl::CreateDeserialized(Context, RawGlobalID); + D = LifetimeExtendedTemporaryDecl::CreateDeserialized(Context, ID); break; case DECL_OBJC_TYPE_PARAM: - D = ObjCTypeParamDecl::CreateDeserialized(Context, RawGlobalID); + D = ObjCTypeParamDecl::CreateDeserialized(Context, ID); break; case DECL_HLSL_BUFFER: - D = HLSLBufferDecl::CreateDeserialized(Context, RawGlobalID); + D = HLSLBufferDecl::CreateDeserialized(Context, ID); break; case DECL_IMPLICIT_CONCEPT_SPECIALIZATION: - D = ImplicitConceptSpecializationDecl::CreateDeserialized( - Context, RawGlobalID, Record.readInt()); + D = ImplicitConceptSpecializationDecl::CreateDeserialized(Context, ID, + Record.readInt()); break; } @@ -4424,8 +4410,9 @@ namespace { // Map global ID of the definition down to the local ID used in this // module file. If there is no such mapping, we'll find nothing here // (or in any module it imports). - DeclID LocalID = Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID); - if (!LocalID) + LocalDeclID LocalID = + Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID); + if (LocalID.isInvalid()) return true; // Perform a binary search to find the local redeclarations for this diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 842ea58656ad..0408eeb6a95b 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3043,7 +3043,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { RecordData Inits; for (Decl *D : Context->getModuleInitializers(Mod)) if (wasDeclEmitted(D)) - Inits.push_back(GetDeclRef(D)); + AddDeclRef(D, Inits); if (!Inits.empty()) Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits); @@ -3226,7 +3226,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, continue; KindDeclPairs.push_back(D->getKind()); - KindDeclPairs.push_back(GetDeclRef(D)); + KindDeclPairs.push_back(GetDeclRef(D).get()); } ++NumLexicalDeclContexts; @@ -3261,7 +3261,7 @@ void ASTWriter::WriteTypeDeclOffsets() { unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); { RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(), - FirstDeclID - NUM_PREDEF_DECL_IDS}; + FirstDeclID.get() - NUM_PREDEF_DECL_IDS}; Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets)); } } @@ -3282,7 +3282,7 @@ void ASTWriter::WriteFileDeclIDsMap() { Info.FirstDeclIndex = FileGroupedDeclIDs.size(); llvm::stable_sort(Info.DeclIDs); for (auto &LocDeclEntry : Info.DeclIDs) - FileGroupedDeclIDs.push_back(LocDeclEntry.second); + FileGroupedDeclIDs.push_back(LocDeclEntry.second.get()); } auto Abbrev = std::make_shared(); @@ -3420,11 +3420,11 @@ public: for (const ObjCMethodList *Method = &Methods.Instance; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - LE.write(Writer.getDeclID(Method->getMethod())); + LE.write((DeclID)Writer.getDeclID(Method->getMethod())); for (const ObjCMethodList *Method = &Methods.Factory; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - LE.write(Writer.getDeclID(Method->getMethod())); + LE.write((DeclID)Writer.getDeclID(Method->getMethod())); assert(Out.tell() - Start == DataLen && "Data length is wrong"); } @@ -3743,8 +3743,8 @@ public: // Only emit declarations that aren't from a chained PCH, though. SmallVector Decls(IdResolver.decls(II)); for (NamedDecl *D : llvm::reverse(Decls)) - LE.write( - Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), D))); + LE.write((DeclID)Writer.getDeclID( + getDeclForLocalLookup(PP.getLangOpts(), D))); } } }; @@ -3860,7 +3860,7 @@ namespace { // Trait used for the on-disk hash table used in the method pool. class ASTDeclContextNameLookupTrait { ASTWriter &Writer; - llvm::SmallVector DeclIDs; + llvm::SmallVector DeclIDs; public: using key_type = DeclarationNameKey; @@ -3893,8 +3893,10 @@ public: data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) { unsigned Start = DeclIDs.size(); - DeclIDs.insert(DeclIDs.end(), DeclIDIterator(FromReader.begin()), - DeclIDIterator(FromReader.end())); + DeclIDs.insert( + DeclIDs.end(), + DeclIDIterator(FromReader.begin()), + DeclIDIterator(FromReader.end())); return std::make_pair(Start, DeclIDs.size()); } @@ -3983,7 +3985,7 @@ public: endian::Writer LE(Out, llvm::endianness::little); uint64_t Start = Out.tell(); (void)Start; for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) - LE.write(DeclIDs[I]); + LE.write((DeclID)DeclIDs[I]); assert(Out.tell() - Start == DataLen && "Data length is wrong"); } }; @@ -4317,7 +4319,8 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { DC = cast(Chain->getKeyDeclaration(cast(DC))); // Write the lookup table - RecordData::value_type Record[] = {UPDATE_VISIBLE, getDeclID(cast(DC))}; + RecordData::value_type Record[] = {UPDATE_VISIBLE, + getDeclID(cast(DC)).get()}; Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable); } @@ -4371,7 +4374,7 @@ void ASTWriter::WriteObjCCategories() { Cat = Class->known_categories_begin(), CatEnd = Class->known_categories_end(); Cat != CatEnd; ++Cat, ++Size) { - assert(getDeclID(*Cat) != 0 && "Bogus category"); + assert(getDeclID(*Cat).isValid() && "Bogus category"); AddDeclRef(*Cat, Categories); } @@ -5089,7 +5092,7 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) { if (!D || !wasDeclEmitted(D)) SemaDeclRefs.push_back(0); else - SemaDeclRefs.push_back(getDeclID(D)); + AddDeclRef(D, SemaDeclRefs); }; AddEmittedDeclRefOrZero(SemaRef.getStdNamespace()); @@ -5100,10 +5103,10 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) { Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); // Write the record containing decls to be checked for deferred diags. - SmallVector DeclsToCheckForDeferredDiags; + RecordData DeclsToCheckForDeferredDiags; for (auto *D : SemaRef.DeclsToCheckForDeferredDiags) if (wasDeclEmitted(D)) - DeclsToCheckForDeferredDiags.push_back(getDeclID(D)); + AddDeclRef(D, DeclsToCheckForDeferredDiags); if (!DeclsToCheckForDeferredDiags.empty()) Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS, DeclsToCheckForDeferredDiags); @@ -5473,7 +5476,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { if (VisibleOffset) VisibleOffset -= DeclTypesBlockStartOffset; - DelayedNamespaceRecord.push_back(getDeclID(NS)); + AddDeclRef(NS, DelayedNamespaceRecord); DelayedNamespaceRecord.push_back(LexicalOffset); DelayedNamespaceRecord.push_back(VisibleOffset); } @@ -5507,7 +5510,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { continue; NewGlobalKindDeclPairs.push_back(D->getKind()); - NewGlobalKindDeclPairs.push_back(GetDeclRef(D)); + NewGlobalKindDeclPairs.push_back(GetDeclRef(D).get()); } auto Abv = std::make_shared(); @@ -5568,7 +5571,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: assert(Update.getDecl() && "no decl to add?"); - Record.push_back(GetDeclRef(Update.getDecl())); + Record.AddDeclRef(Update.getDecl()); break; case UPD_CXX_ADDED_FUNCTION_DEFINITION: @@ -5709,7 +5712,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { } } - OffsetsRecord.push_back(GetDeclRef(D)); + AddDeclRef(D, OffsetsRecord); OffsetsRecord.push_back(Record.Emit(DECL_UPDATES)); } } @@ -5974,18 +5977,18 @@ void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) { if (!wasDeclEmitted(D)) return; - Record.push_back(GetDeclRef(D)); + Record.push_back(GetDeclRef(D).get()); } void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { - Record.push_back(GetDeclRef(D)); + Record.push_back(GetDeclRef(D).get()); } -DeclID ASTWriter::GetDeclRef(const Decl *D) { +LocalDeclID ASTWriter::GetDeclRef(const Decl *D) { assert(WritingAST && "Cannot request a declaration ID before AST writing"); if (!D) { - return 0; + return LocalDeclID(); } // If the DeclUpdate from the GMF gets touched, emit it. @@ -5999,14 +6002,14 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) { // If D comes from an AST file, its declaration ID is already known and // fixed. if (D->isFromASTFile()) - return D->getGlobalID(); + return LocalDeclID(D->getGlobalID()); assert(!(reinterpret_cast(D) & 0x01) && "Invalid decl pointer"); - DeclID &ID = DeclIDs[D]; - if (ID == 0) { + LocalDeclID &ID = DeclIDs[D]; + if (ID.isInvalid()) { if (DoneWritingDeclsAndTypes) { assert(0 && "New decl seen after serializing all the decls to emit!"); - return 0; + return LocalDeclID(); } // We haven't seen this declaration before. Give it a new ID and @@ -6018,14 +6021,14 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) { return ID; } -DeclID ASTWriter::getDeclID(const Decl *D) { +LocalDeclID ASTWriter::getDeclID(const Decl *D) { if (!D) - return 0; + return LocalDeclID(); // If D comes from an AST file, its declaration ID is already known and // fixed. if (D->isFromASTFile()) - return D->getGlobalID(); + return LocalDeclID(D->getGlobalID()); assert(DeclIDs.contains(D) && "Declaration not emitted!"); return DeclIDs[D]; @@ -6046,8 +6049,8 @@ bool ASTWriter::wasDeclEmitted(const Decl *D) const { return Emitted; } -void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { - assert(ID); +void ASTWriter::associateDeclWithFile(const Decl *D, LocalDeclID ID) { + assert(ID.isValid()); assert(D); SourceLocation Loc = D->getLocation(); @@ -6079,7 +6082,7 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { if (!Info) Info = std::make_unique(); - std::pair LocDecl(Offset, ID); + std::pair LocDecl(Offset, ID); LocDeclIDsTy &Decls = Info->DeclIDs; Decls.push_back(LocDecl); } @@ -6349,7 +6352,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType(); Record->push_back(ModulesDebugInfo); if (ModulesDebugInfo) - Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D)); + Writer->AddDeclRef(D, Writer->ModularCodegenDecls); // IsLambda bit is already saved. @@ -6453,7 +6456,7 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { // Note, this will get called multiple times, once one the reader starts up // and again each time it's done reading a PCH or module. - FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls(); + FirstDeclID = LocalDeclID(NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls()); FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros(); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index fe867192b717..0edc4feda3ef 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -223,9 +223,9 @@ namespace clang { assert(!Common->LazySpecializations); } - ArrayRef LazySpecializations; + ArrayRef LazySpecializations; if (auto *LS = Common->LazySpecializations) - LazySpecializations = llvm::ArrayRef(LS + 1, LS[0]); + LazySpecializations = llvm::ArrayRef(LS + 1, LS[0].get()); // Add a slot to the record for the number of specializations. unsigned I = Record.size(); @@ -243,7 +243,9 @@ namespace clang { assert(D->isCanonicalDecl() && "non-canonical decl in set"); AddFirstDeclFromEachModule(D, /*IncludeLocal*/true); } - Record.append(LazySpecializations.begin(), LazySpecializations.end()); + Record.append( + DeclIDIterator(LazySpecializations.begin()), + DeclIDIterator(LazySpecializations.end())); // Update the size entry we added earlier. Record[I] = Record.size() - I - 1; @@ -1166,7 +1168,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(VarDeclBits); if (ModulesCodegen) - Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D)); + Writer.AddDeclRef(D, Writer.ModularCodegenDecls); if (D->hasAttr()) { BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D); @@ -2786,10 +2788,10 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { "serializing"); // Determine the ID for this declaration. - DeclID ID; + LocalDeclID ID; assert(!D->isFromASTFile() && "should not be emitting imported decl"); - DeclID &IDR = DeclIDs[D]; - if (IDR == 0) + LocalDeclID &IDR = DeclIDs[D]; + if (IDR.isInvalid()) IDR = NextDeclID++; ID = IDR; @@ -2807,7 +2809,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Record the offset for this declaration SourceLocation Loc = D->getLocation(); - unsigned Index = ID - FirstDeclID; + unsigned Index = ID.get() - FirstDeclID.get(); if (DeclOffsets.size() == Index) DeclOffsets.emplace_back(getAdjustedLocation(Loc), Offset, DeclTypesBlockStartOffset); @@ -2827,7 +2829,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Note declarations that should be deserialized eagerly so that we can add // them to a record in the AST file later. if (isRequiredDecl(D, Context, WritingModule)) - EagerlyDeserializedDecls.push_back(ID); + AddDeclRef(D, EagerlyDeserializedDecls); } void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { @@ -2863,7 +2865,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { } Record->push_back(ModulesCodegen); if (ModulesCodegen) - Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(FD)); + Writer->AddDeclRef(FD, Writer->ModularCodegenDecls); if (auto *CD = dyn_cast(FD)) { Record->push_back(CD->getNumCtorInitializers()); if (CD->getNumCtorInitializers()) diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h index cefec15a7980..17f1506036c6 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h @@ -30,7 +30,7 @@ public: ~ExternalASTSourceWrapper() override; - clang::Decl *GetExternalDecl(uint32_t ID) override { + clang::Decl *GetExternalDecl(clang::GlobalDeclID ID) override { return m_Source->GetExternalDecl(ID); } @@ -266,7 +266,7 @@ public: // ExternalASTSource. //===--------------------------------------------------------------------===// - clang::Decl *GetExternalDecl(uint32_t ID) override { + clang::Decl *GetExternalDecl(clang::GlobalDeclID ID) override { for (size_t i = 0; i < Sources.size(); ++i) if (clang::Decl *Result = Sources[i]->GetExternalDecl(ID)) return Result; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h index f34e4661a81c..83c910477acc 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h @@ -49,7 +49,7 @@ public: ~ClangASTSource() override; /// Interface stubs. - clang::Decl *GetExternalDecl(uint32_t) override { return nullptr; } + clang::Decl *GetExternalDecl(clang::GlobalDeclID) override { return nullptr; } clang::Stmt *GetExternalDeclStmt(uint64_t) override { return nullptr; } clang::Selector GetExternalSelector(uint32_t) override { return clang::Selector(); diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 662da313af59..96909425dedd 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -1230,7 +1230,7 @@ CompilerType TypeSystemClang::CreateRecordType( // complete definition just in case. bool has_name = !name.empty(); - CXXRecordDecl *decl = CXXRecordDecl::CreateDeserialized(ast, 0); + CXXRecordDecl *decl = CXXRecordDecl::CreateDeserialized(ast, GlobalDeclID()); decl->setTagKind(static_cast(kind)); decl->setDeclContext(decl_ctx); if (has_name) @@ -1402,7 +1402,7 @@ clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( TemplateParameterList *template_param_list = CreateTemplateParameterList( ast, template_param_infos, template_param_decls); FunctionTemplateDecl *func_tmpl_decl = - FunctionTemplateDecl::CreateDeserialized(ast, 0); + FunctionTemplateDecl::CreateDeserialized(ast, GlobalDeclID()); func_tmpl_decl->setDeclContext(decl_ctx); func_tmpl_decl->setLocation(func_decl->getLocation()); func_tmpl_decl->setDeclName(func_decl->getDeclName()); @@ -1564,7 +1564,8 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( TemplateParameterList *template_param_list = CreateTemplateParameterList( ast, template_param_infos, template_param_decls); - CXXRecordDecl *template_cxx_decl = CXXRecordDecl::CreateDeserialized(ast, 0); + CXXRecordDecl *template_cxx_decl = + CXXRecordDecl::CreateDeserialized(ast, GlobalDeclID()); template_cxx_decl->setTagKind(static_cast(kind)); // What decl context do we use here? TU? The actual decl context? template_cxx_decl->setDeclContext(decl_ctx); @@ -1581,7 +1582,8 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( // template_cxx_decl->startDefinition(); // template_cxx_decl->completeDefinition(); - class_template_decl = ClassTemplateDecl::CreateDeserialized(ast, 0); + class_template_decl = + ClassTemplateDecl::CreateDeserialized(ast, GlobalDeclID()); // What decl context do we use here? TU? The actual decl context? class_template_decl->setDeclContext(decl_ctx); class_template_decl->setDeclName(decl_name); @@ -1642,7 +1644,7 @@ TypeSystemClang::CreateClassTemplateSpecializationDecl( ast, template_param_infos.GetParameterPackArgs()); } ClassTemplateSpecializationDecl *class_template_specialization_decl = - ClassTemplateSpecializationDecl::CreateDeserialized(ast, 0); + ClassTemplateSpecializationDecl::CreateDeserialized(ast, GlobalDeclID()); class_template_specialization_decl->setTagKind( static_cast(kind)); class_template_specialization_decl->setDeclContext(decl_ctx); @@ -1792,7 +1794,8 @@ CompilerType TypeSystemClang::CreateObjCClass( if (!decl_ctx) decl_ctx = ast.getTranslationUnitDecl(); - ObjCInterfaceDecl *decl = ObjCInterfaceDecl::CreateDeserialized(ast, 0); + ObjCInterfaceDecl *decl = + ObjCInterfaceDecl::CreateDeserialized(ast, GlobalDeclID()); decl->setDeclContext(decl_ctx); decl->setDeclName(&ast.Idents.get(name)); /*isForwardDecl,*/ @@ -1900,7 +1903,7 @@ TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx, OptionalClangModuleID owning_module) { if (ctx) { clang::BlockDecl *decl = - clang::BlockDecl::CreateDeserialized(getASTContext(), 0); + clang::BlockDecl::CreateDeserialized(getASTContext(), GlobalDeclID()); decl->setDeclContext(ctx); ctx->addDecl(decl); SetOwningModule(decl, owning_module); @@ -1969,7 +1972,7 @@ clang::VarDecl *TypeSystemClang::CreateVariableDeclaration( const char *name, clang::QualType type) { if (decl_context) { clang::VarDecl *var_decl = - clang::VarDecl::CreateDeserialized(getASTContext(), 0); + clang::VarDecl::CreateDeserialized(getASTContext(), GlobalDeclID()); var_decl->setDeclContext(decl_context); if (name && name[0]) var_decl->setDeclName(&getASTContext().Idents.getOwn(name)); @@ -2129,7 +2132,7 @@ FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( clang::DeclarationName declarationName = GetDeclarationName(name, function_clang_type); - func_decl = FunctionDecl::CreateDeserialized(ast, 0); + func_decl = FunctionDecl::CreateDeserialized(ast, GlobalDeclID()); func_decl->setDeclContext(decl_ctx); func_decl->setDeclName(declarationName); func_decl->setType(ClangUtil::GetQualType(function_clang_type)); @@ -2190,7 +2193,7 @@ ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( const char *name, const CompilerType ¶m_type, int storage, bool add_decl) { ASTContext &ast = getASTContext(); - auto *decl = ParmVarDecl::CreateDeserialized(ast, 0); + auto *decl = ParmVarDecl::CreateDeserialized(ast, GlobalDeclID()); decl->setDeclContext(decl_ctx); if (name && name[0]) decl->setDeclName(&ast.Idents.get(name)); @@ -2295,7 +2298,7 @@ CompilerType TypeSystemClang::CreateEnumerationType( // TODO: ask about these... // const bool IsFixed = false; - EnumDecl *enum_decl = EnumDecl::CreateDeserialized(ast, 0); + EnumDecl *enum_decl = EnumDecl::CreateDeserialized(ast, GlobalDeclID()); enum_decl->setDeclContext(decl_ctx); if (!name.empty()) enum_decl->setDeclName(&ast.Idents.get(name)); @@ -4534,7 +4537,7 @@ CompilerType TypeSystemClang::CreateTypedef( decl_ctx = getASTContext().getTranslationUnitDecl(); clang::TypedefDecl *decl = - clang::TypedefDecl::CreateDeserialized(clang_ast, 0); + clang::TypedefDecl::CreateDeserialized(clang_ast, GlobalDeclID()); decl->setDeclContext(decl_ctx); decl->setDeclName(&clang_ast.Idents.get(typedef_name)); decl->setTypeSourceInfo(clang_ast.getTrivialTypeSourceInfo(qual_type)); @@ -7291,7 +7294,7 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType( clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type); if (record_decl) { - field = clang::FieldDecl::CreateDeserialized(clang_ast, 0); + field = clang::FieldDecl::CreateDeserialized(clang_ast, GlobalDeclID()); field->setDeclContext(record_decl); field->setDeclName(ident); field->setType(ClangUtil::GetQualType(field_clang_type)); @@ -7338,7 +7341,8 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType( field_clang_type.GetCompleteType(); - auto *ivar = clang::ObjCIvarDecl::CreateDeserialized(clang_ast, 0); + auto *ivar = + clang::ObjCIvarDecl::CreateDeserialized(clang_ast, GlobalDeclID()); ivar->setDeclContext(class_interface_decl); ivar->setDeclName(ident); ivar->setType(ClangUtil::GetQualType(field_clang_type)); @@ -7504,7 +7508,8 @@ clang::VarDecl *TypeSystemClang::AddVariableToRecordType( if (!name.empty()) ident = &ast->getASTContext().Idents.get(name); - var_decl = clang::VarDecl::CreateDeserialized(ast->getASTContext(), 0); + var_decl = + clang::VarDecl::CreateDeserialized(ast->getASTContext(), GlobalDeclID()); var_decl->setDeclContext(record_decl); var_decl->setDeclName(ident); var_decl->setType(ClangUtil::GetQualType(var_type)); @@ -7605,8 +7610,8 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType( : clang::ExplicitSpecKind::ResolvedFalse); if (name.starts_with("~")) { - cxx_dtor_decl = - clang::CXXDestructorDecl::CreateDeserialized(getASTContext(), 0); + cxx_dtor_decl = clang::CXXDestructorDecl::CreateDeserialized( + getASTContext(), GlobalDeclID()); cxx_dtor_decl->setDeclContext(cxx_record_decl); cxx_dtor_decl->setDeclName( getASTContext().DeclarationNames.getCXXDestructorName( @@ -7618,7 +7623,7 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType( cxx_method_decl = cxx_dtor_decl; } else if (decl_name == cxx_record_decl->getDeclName()) { cxx_ctor_decl = clang::CXXConstructorDecl::CreateDeserialized( - getASTContext(), 0, 0); + getASTContext(), GlobalDeclID(), 0); cxx_ctor_decl->setDeclContext(cxx_record_decl); cxx_ctor_decl->setDeclName( getASTContext().DeclarationNames.getCXXConstructorName( @@ -7644,8 +7649,8 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType( if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount( is_method, op_kind, num_params)) return nullptr; - cxx_method_decl = - clang::CXXMethodDecl::CreateDeserialized(getASTContext(), 0); + cxx_method_decl = clang::CXXMethodDecl::CreateDeserialized( + getASTContext(), GlobalDeclID()); cxx_method_decl->setDeclContext(cxx_record_decl); cxx_method_decl->setDeclName( getASTContext().DeclarationNames.getCXXOperatorName(op_kind)); @@ -7656,7 +7661,8 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType( } else if (num_params == 0) { // Conversion operators don't take params... auto *cxx_conversion_decl = - clang::CXXConversionDecl::CreateDeserialized(getASTContext(), 0); + clang::CXXConversionDecl::CreateDeserialized(getASTContext(), + GlobalDeclID()); cxx_conversion_decl->setDeclContext(cxx_record_decl); cxx_conversion_decl->setDeclName( getASTContext().DeclarationNames.getCXXConversionFunctionName( @@ -7671,8 +7677,8 @@ clang::CXXMethodDecl *TypeSystemClang::AddMethodToCXXRecordType( } if (cxx_method_decl == nullptr) { - cxx_method_decl = - clang::CXXMethodDecl::CreateDeserialized(getASTContext(), 0); + cxx_method_decl = clang::CXXMethodDecl::CreateDeserialized( + getASTContext(), GlobalDeclID()); cxx_method_decl->setDeclContext(cxx_record_decl); cxx_method_decl->setDeclName(decl_name); cxx_method_decl->setType(method_qual_type); @@ -7855,7 +7861,7 @@ bool TypeSystemClang::AddObjCClassProperty( ClangUtil::GetQualType(property_clang_type)); clang::ObjCPropertyDecl *property_decl = - clang::ObjCPropertyDecl::CreateDeserialized(clang_ast, 0); + clang::ObjCPropertyDecl::CreateDeserialized(clang_ast, GlobalDeclID()); property_decl->setDeclContext(class_interface_decl); property_decl->setDeclName(&clang_ast.Idents.get(property_name)); property_decl->setType(ivar_decl @@ -7944,7 +7950,8 @@ bool TypeSystemClang::AddObjCClassProperty( clang::ObjCImplementationControl::None; const bool HasRelatedResultType = false; - getter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0); + getter = + clang::ObjCMethodDecl::CreateDeserialized(clang_ast, GlobalDeclID()); getter->setDeclName(getter_sel); getter->setReturnType(ClangUtil::GetQualType(property_clang_type_to_access)); getter->setDeclContext(class_interface_decl); @@ -7986,7 +7993,8 @@ bool TypeSystemClang::AddObjCClassProperty( clang::ObjCImplementationControl::None; const bool HasRelatedResultType = false; - setter = clang::ObjCMethodDecl::CreateDeserialized(clang_ast, 0); + setter = + clang::ObjCMethodDecl::CreateDeserialized(clang_ast, GlobalDeclID()); setter->setDeclName(setter_sel); setter->setReturnType(result_type); setter->setDeclContext(class_interface_decl); @@ -8114,7 +8122,8 @@ clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType( return nullptr; // some debug information is corrupt. We are not going to // deal with it. - auto *objc_method_decl = clang::ObjCMethodDecl::CreateDeserialized(ast, 0); + auto *objc_method_decl = + clang::ObjCMethodDecl::CreateDeserialized(ast, GlobalDeclID()); objc_method_decl->setDeclName(method_selector); objc_method_decl->setReturnType(method_function_prototype->getReturnType()); objc_method_decl->setDeclContext( @@ -8360,7 +8369,8 @@ clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType( return nullptr; clang::EnumConstantDecl *enumerator_decl = - clang::EnumConstantDecl::CreateDeserialized(getASTContext(), 0); + clang::EnumConstantDecl::CreateDeserialized(getASTContext(), + GlobalDeclID()); enumerator_decl->setDeclContext(enutype->getDecl()); if (name && name[0]) enumerator_decl->setDeclName(&getASTContext().Idents.get(name)); -- GitLab From 565bdb55453f0bdd59d9325b8a748cb42e6df95b Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 25 Apr 2024 09:06:48 +0200 Subject: [PATCH 060/733] [lldb] Add SB API to access static constexpr member values (#89730) The main change is the addition of a new SBTypeStaticField class, representing a static member of a class. It can be retrieved created through SBType::GetStaticFieldWithName. It contains several methods (GetName, GetMangledName, etc.) whose meaning is hopefully obvious. The most interesting method is lldb::SBValue GetConstantValue(lldb::SBTarget) which returns a the value of the field -- if it is a compile time constant. The reason for that is that only constants have their values represented in the clang AST. For non-constants, we need to go back to the module containing that constant, and ask retrieve the associated ValueObjectVariable. That's easy enough if the we are still in the type system of the module (because then the type system will contain the pointer to the module symbol file), but it's hard when the type has been copied into another AST (e.g. during expression evaluation). To do that we would need to walk the ast import chain backwards to find the source TypeSystem, and I haven't found a nice way to do that. Another possibility would be to use the mangled name of the variable to perform a lookup (in all modules). That is sort of what happens when evaluating the variable in an expression (which does work), but I did not want to commit to that implementation as it's not necessary for my use case (and if anyone wants to, he can use the GetMangledName function and perform the lookup manually). The patch adds a couple of new TypeSystem functions to surface the information needed to implement this functionality. --- lldb/include/lldb/API/SBTarget.h | 1 + lldb/include/lldb/API/SBType.h | 32 +++++++ lldb/include/lldb/API/SBValue.h | 1 + lldb/include/lldb/Symbol/CompilerDecl.h | 7 ++ lldb/include/lldb/Symbol/CompilerType.h | 2 + lldb/include/lldb/Symbol/TypeSystem.h | 9 ++ lldb/source/API/SBType.cpp | 88 +++++++++++++++++++ .../TypeSystem/Clang/TypeSystemClang.cpp | 52 +++++++++++ .../TypeSystem/Clang/TypeSystemClang.h | 8 ++ lldb/source/Symbol/CompilerDecl.cpp | 9 ++ lldb/source/Symbol/CompilerType.cpp | 6 ++ lldb/test/API/python_api/type/TestTypeList.py | 33 +++++++ lldb/test/API/python_api/type/main.cpp | 3 + 13 files changed, 251 insertions(+) diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index 3644ac056da3..823615e6a36d 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -954,6 +954,7 @@ protected: friend class SBSection; friend class SBSourceManager; friend class SBSymbol; + friend class SBTypeStaticField; friend class SBValue; friend class SBVariablesOptions; diff --git a/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h index 9980fe121830..5b9ff2170b2b 100644 --- a/lldb/include/lldb/API/SBType.h +++ b/lldb/include/lldb/API/SBType.h @@ -107,6 +107,35 @@ protected: lldb::TypeMemberFunctionImplSP m_opaque_sp; }; +class LLDB_API SBTypeStaticField { +public: + SBTypeStaticField(); + + SBTypeStaticField(const lldb::SBTypeStaticField &rhs); + lldb::SBTypeStaticField &operator=(const lldb::SBTypeStaticField &rhs); + + ~SBTypeStaticField(); + + explicit operator bool() const; + + bool IsValid() const; + + const char *GetName(); + + const char *GetMangledName(); + + lldb::SBType GetType(); + + lldb::SBValue GetConstantValue(lldb::SBTarget target); + +protected: + friend class SBType; + + explicit SBTypeStaticField(lldb_private::CompilerDecl decl); + + std::unique_ptr m_opaque_up; +}; + class SBType { public: SBType(); @@ -182,6 +211,8 @@ public: lldb::SBTypeMember GetVirtualBaseClassAtIndex(uint32_t idx); + lldb::SBTypeStaticField GetStaticFieldWithName(const char *name); + lldb::SBTypeEnumMemberList GetEnumMembers(); uint32_t GetNumberOfTemplateArguments(); @@ -242,6 +273,7 @@ protected: friend class SBTypeNameSpecifier; friend class SBTypeMember; friend class SBTypeMemberFunction; + friend class SBTypeStaticField; friend class SBTypeList; friend class SBValue; friend class SBWatchpoint; diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index bbcccaab51aa..67f55ce7da28 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -426,6 +426,7 @@ protected: friend class SBModule; friend class SBTarget; friend class SBThread; + friend class SBTypeStaticField; friend class SBTypeSummary; friend class SBValueList; diff --git a/lldb/include/lldb/Symbol/CompilerDecl.h b/lldb/include/lldb/Symbol/CompilerDecl.h index 825a4f15836f..5c99cae3781c 100644 --- a/lldb/include/lldb/Symbol/CompilerDecl.h +++ b/lldb/include/lldb/Symbol/CompilerDecl.h @@ -73,6 +73,9 @@ public: CompilerDeclContext GetDeclContext() const; + // If this decl has a type, return it. + CompilerType GetType() const; + // If this decl represents a function, return the return type CompilerType GetFunctionReturnType() const; @@ -91,6 +94,10 @@ public: /// the subsequent entry, so the topmost entry is the global namespace. std::vector GetCompilerContext() const; + // If decl represents a constant value, return it. Otherwise, return an + // invalid/empty Scalar. + Scalar GetConstantValue() const; + private: TypeSystem *m_type_system = nullptr; void *m_opaque_decl = nullptr; diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h index b71c531f2163..9e889a53086b 100644 --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -416,6 +416,8 @@ public: CompilerType GetVirtualBaseClassAtIndex(size_t idx, uint32_t *bit_offset_ptr) const; + CompilerDecl GetStaticFieldWithName(llvm::StringRef name) const; + uint32_t GetIndexOfFieldWithName(const char *name, CompilerType *field_compiler_type = nullptr, uint64_t *bit_offset_ptr = nullptr, diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index 3a927d313b82..ad3b853227a9 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -27,6 +27,8 @@ #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/Type.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" #include "lldb/lldb-types.h" @@ -110,6 +112,8 @@ public: virtual std::vector DeclGetCompilerContext(void *opaque_decl); + virtual Scalar DeclGetConstantValue(void *opaque_decl) { return Scalar(); } + virtual CompilerType GetTypeForDecl(void *opaque_decl) = 0; // CompilerDeclContext functions @@ -339,6 +343,11 @@ public: GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) = 0; + virtual CompilerDecl GetStaticFieldWithName(lldb::opaque_compiler_type_t type, + llvm::StringRef name) { + return CompilerDecl(); + } + virtual CompilerType GetChildCompilerTypeAtIndex( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, bool omit_empty_base_classes, diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp index ac0e56303fae..6cecb5c9ea81 100644 --- a/lldb/source/API/SBType.cpp +++ b/lldb/source/API/SBType.cpp @@ -7,16 +7,21 @@ //===----------------------------------------------------------------------===// #include "lldb/API/SBType.h" +#include "Utils.h" #include "lldb/API/SBDefines.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBTypeEnumMember.h" #include "lldb/Core/Mangled.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Instrumentation.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Stream.h" #include "llvm/ADT/APSInt.h" @@ -325,6 +330,79 @@ lldb::SBTypeMemberFunction SBType::GetMemberFunctionAtIndex(uint32_t idx) { return sb_func_type; } +SBTypeStaticField::SBTypeStaticField() { LLDB_INSTRUMENT_VA(this); } + +SBTypeStaticField::SBTypeStaticField(lldb_private::CompilerDecl decl) + : m_opaque_up(decl ? std::make_unique(decl) : nullptr) {} + +SBTypeStaticField::SBTypeStaticField(const SBTypeStaticField &rhs) { + LLDB_INSTRUMENT_VA(this, rhs); + + m_opaque_up = clone(rhs.m_opaque_up); +} + +SBTypeStaticField &SBTypeStaticField::operator=(const SBTypeStaticField &rhs) { + LLDB_INSTRUMENT_VA(this, rhs); + + m_opaque_up = clone(rhs.m_opaque_up); + return *this; +} + +SBTypeStaticField::~SBTypeStaticField() { LLDB_INSTRUMENT_VA(this); } + +SBTypeStaticField::operator bool() const { + LLDB_INSTRUMENT_VA(this); + + return IsValid(); +} + +bool SBTypeStaticField::IsValid() const { + LLDB_INSTRUMENT_VA(this); + + return m_opaque_up != nullptr; +} + +const char *SBTypeStaticField::GetName() { + LLDB_INSTRUMENT_VA(this); + + if (!IsValid()) + return ""; + return m_opaque_up->GetName().GetCString(); +} + +const char *SBTypeStaticField::GetMangledName() { + LLDB_INSTRUMENT_VA(this); + + if (!IsValid()) + return ""; + return m_opaque_up->GetMangledName().GetCString(); +} + +SBType SBTypeStaticField::GetType() { + LLDB_INSTRUMENT_VA(this); + + if (!IsValid()) + return SBType(); + return SBType(m_opaque_up->GetType()); +} + +SBValue SBTypeStaticField::GetConstantValue(lldb::SBTarget target) { + LLDB_INSTRUMENT_VA(this, target); + + if (!IsValid()) + return SBValue(); + + Scalar value = m_opaque_up->GetConstantValue(); + if (!value.IsValid()) + return SBValue(); + DataExtractor data; + value.GetData(data); + auto value_obj_sp = ValueObjectConstResult::Create( + target.GetSP().get(), m_opaque_up->GetType(), m_opaque_up->GetName(), + data); + return SBValue(std::move(value_obj_sp)); +} + lldb::SBType SBType::GetUnqualifiedType() { LLDB_INSTRUMENT_VA(this); @@ -438,6 +516,16 @@ SBTypeMember SBType::GetVirtualBaseClassAtIndex(uint32_t idx) { return sb_type_member; } +SBTypeStaticField SBType::GetStaticFieldWithName(const char *name) { + LLDB_INSTRUMENT_VA(this, name); + + if (!IsValid() || !name) + return SBTypeStaticField(); + + return SBTypeStaticField(m_opaque_sp->GetCompilerType(/*prefer_dynamic=*/true) + .GetStaticFieldWithName(name)); +} + SBTypeEnumMemberList SBType::GetEnumMembers() { LLDB_INSTRUMENT_VA(this); diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 96909425dedd..5da94adb771f 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -9,6 +9,7 @@ #include "TypeSystemClang.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/ExprCXX.h" #include "llvm/Support/Casting.h" #include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatVariadic.h" @@ -1148,6 +1149,8 @@ CompilerType TypeSystemClang::GetTypeForDecl(clang::NamedDecl *decl) { return GetTypeForDecl(interface_decl); if (clang::TagDecl *tag_decl = llvm::dyn_cast(decl)) return GetTypeForDecl(tag_decl); + if (clang::ValueDecl *value_decl = llvm::dyn_cast(decl)) + return GetTypeForDecl(value_decl); return CompilerType(); } @@ -1159,6 +1162,10 @@ CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) { return GetType(getASTContext().getObjCInterfaceType(decl)); } +CompilerType TypeSystemClang::GetTypeForDecl(clang::ValueDecl *value_decl) { + return GetType(value_decl->getType()); +} + #pragma mark Structure, Unions, Classes void TypeSystemClang::SetOwningModule(clang::Decl *decl, @@ -5906,6 +5913,36 @@ CompilerType TypeSystemClang::GetVirtualBaseClassAtIndex( return CompilerType(); } +CompilerDecl +TypeSystemClang::GetStaticFieldWithName(lldb::opaque_compiler_type_t type, + llvm::StringRef name) { + clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); + switch (qual_type->getTypeClass()) { + case clang::Type::Record: { + if (!GetCompleteType(type)) + return CompilerDecl(); + + const clang::RecordType *record_type = + llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + + clang::DeclarationName decl_name(&getASTContext().Idents.get(name)); + for (NamedDecl *decl : record_decl->lookup(decl_name)) { + auto *var_decl = dyn_cast(decl); + if (!var_decl || var_decl->getStorageClass() != clang::SC_Static) + continue; + + return CompilerDecl(this, var_decl); + } + break; + } + + default: + break; + } + return CompilerDecl(); +} + // If a pointer to a pointee type (the clang_type arg) says that it has no // children, then we either need to trust it, or override it and return a // different result. For example, an "int *" has one child that is an integer, @@ -9087,6 +9124,21 @@ CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl, return CompilerType(); } +Scalar TypeSystemClang::DeclGetConstantValue(void *opaque_decl) { + clang::Decl *decl = static_cast(opaque_decl); + clang::VarDecl *var_decl = llvm::dyn_cast(decl); + if (!var_decl) + return Scalar(); + clang::Expr *init_expr = var_decl->getInit(); + if (!init_expr) + return Scalar(); + std::optional value = + init_expr->getIntegerConstantExpr(getASTContext()); + if (!value) + return Scalar(); + return Scalar(*value); +} + // CompilerDeclContext functions std::vector TypeSystemClang::DeclContextFindDeclByName( diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 68b82e9688f1..62f14df7638d 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -22,6 +22,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTFwd.h" +#include "clang/AST/Decl.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/Basic/TargetInfo.h" @@ -251,6 +252,8 @@ public: CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl); + CompilerType GetTypeForDecl(clang::ValueDecl *value_decl); + template CompilerType GetTypeForIdentifier(llvm::StringRef type_name, @@ -559,6 +562,8 @@ public: std::vector DeclGetCompilerContext(void *opaque_decl) override; + Scalar DeclGetConstantValue(void *opaque_decl) override; + CompilerType GetTypeForDecl(void *opaque_decl) override; // CompilerDeclContext override functions @@ -868,6 +873,9 @@ public: size_t idx, uint32_t *bit_offset_ptr) override; + CompilerDecl GetStaticFieldWithName(lldb::opaque_compiler_type_t type, + llvm::StringRef name) override; + static uint32_t GetNumPointeeChildren(clang::QualType type); CompilerType GetChildCompilerTypeAtIndex( diff --git a/lldb/source/Symbol/CompilerDecl.cpp b/lldb/source/Symbol/CompilerDecl.cpp index 0eb630e5b9e1..5fa0a32f041a 100644 --- a/lldb/source/Symbol/CompilerDecl.cpp +++ b/lldb/source/Symbol/CompilerDecl.cpp @@ -9,6 +9,7 @@ #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/TypeSystem.h" +#include "lldb/Utility/Scalar.h" using namespace lldb_private; @@ -24,6 +25,10 @@ CompilerDeclContext CompilerDecl::GetDeclContext() const { return m_type_system->DeclGetDeclContext(m_opaque_decl); } +CompilerType CompilerDecl::GetType() const { + return m_type_system->GetTypeForDecl(m_opaque_decl); +} + CompilerType CompilerDecl::GetFunctionReturnType() const { return m_type_system->DeclGetFunctionReturnType(m_opaque_decl); } @@ -52,3 +57,7 @@ std::vector CompilerDecl::GetCompilerContext() const { return m_type_system->DeclGetCompilerContext(m_opaque_decl); } + +Scalar CompilerDecl::GetConstantValue() const { + return m_type_system->DeclGetConstantValue(m_opaque_decl); +} diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp index 96e74b890d2d..9523fb6ea77c 100644 --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -849,6 +849,12 @@ CompilerType::GetVirtualBaseClassAtIndex(size_t idx, return CompilerType(); } +CompilerDecl CompilerType::GetStaticFieldWithName(llvm::StringRef name) const { + if (IsValid()) + return GetTypeSystem()->GetStaticFieldWithName(m_type, name); + return CompilerDecl(); +} + uint32_t CompilerType::GetIndexOfFieldWithName( const char *name, CompilerType *field_compiler_type_ptr, uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, diff --git a/lldb/test/API/python_api/type/TestTypeList.py b/lldb/test/API/python_api/type/TestTypeList.py index c647c2bcdccb..81c44f7a39d6 100644 --- a/lldb/test/API/python_api/type/TestTypeList.py +++ b/lldb/test/API/python_api/type/TestTypeList.py @@ -33,6 +33,32 @@ class TypeAndTypeListTestCase(TestBase): self.assertTrue(pointer_masks2_type) self.DebugSBType(pointer_masks2_type) + def _find_static_field_in_Task_pointer(self, task_pointer): + self.assertTrue(task_pointer) + self.DebugSBType(task_pointer) + + task_type = task_pointer.GetPointeeType() + self.assertTrue(task_type) + self.DebugSBType(task_type) + + static_constexpr_field = task_type.GetStaticFieldWithName( + "static_constexpr_field" + ) + self.assertTrue(static_constexpr_field) + self.assertEqual(static_constexpr_field.GetName(), "static_constexpr_field") + self.assertEqual(static_constexpr_field.GetType().GetName(), "const long") + + value = static_constexpr_field.GetConstantValue(self.target()) + self.DebugSBValue(value) + self.assertEqual(value.GetValueAsSigned(), 47) + + static_mutable_field = task_type.GetStaticFieldWithName("static_mutable_field") + self.assertTrue(static_mutable_field) + self.assertEqual(static_mutable_field.GetName(), "static_mutable_field") + self.assertEqual(static_mutable_field.GetType().GetName(), "int") + + self.assertFalse(static_mutable_field.GetConstantValue(self.target())) + @skipIf(compiler="clang", compiler_version=["<", "17.0"]) def test(self): """Exercise SBType and SBTypeList API.""" @@ -175,6 +201,13 @@ class TypeAndTypeListTestCase(TestBase): frame0.EvaluateExpression("pointer").GetType() ) + self._find_static_field_in_Task_pointer( + frame0.FindVariable("task_head").GetType() + ) + self._find_static_field_in_Task_pointer( + frame0.EvaluateExpression("task_head").GetType() + ) + # We'll now get the child member 'id' from 'task_head'. id = task_head.GetChildMemberWithName("id") self.DebugSBValue(id) diff --git a/lldb/test/API/python_api/type/main.cpp b/lldb/test/API/python_api/type/main.cpp index 391f58e3e587..c86644d91827 100644 --- a/lldb/test/API/python_api/type/main.cpp +++ b/lldb/test/API/python_api/type/main.cpp @@ -27,12 +27,15 @@ public: enum E : unsigned char {} e; union U { } u; + static constexpr long static_constexpr_field = 47; + static int static_mutable_field; Task(int i, Task *n): id(i), next(n), type(TASK_TYPE_1) {} }; +int Task::static_mutable_field = 42; template struct PointerInfo { enum Masks1 { pointer_mask }; -- GitLab From 8bfdbb9570c87fc98c9d6b41409e4c59ba285f51 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 25 Apr 2024 16:14:54 +0900 Subject: [PATCH 061/733] [InstCombine] Remove redundant shift folds (NFCI) (#90016) These are already handled by canEvaluateShifted/getShiftedValue (one-use only), and also in reassociateShiftAmtsOfTwoSameDirectionShifts (also multi-use), so let's at least get rid of the *third* implementation... --- .../Transforms/InstCombine/InstCombineShifts.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 244f03a1bc2b..1cb21a1d81af 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -1120,14 +1120,6 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) { return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Ty, Mask)); } - if (match(Op0, m_Shl(m_Value(X), m_APInt(C1))) && C1->ult(BitWidth)) { - unsigned AmtSum = ShAmtC + C1->getZExtValue(); - // Oversized shifts are simplified to zero in InstSimplify. - if (AmtSum < BitWidth) - // (X << C1) << C2 --> X << (C1 + C2) - return BinaryOperator::CreateShl(X, ConstantInt::get(Ty, AmtSum)); - } - // If we have an opposite shift by the same amount, we may be able to // reorder binops and shifts to eliminate math/logic. auto isSuitableBinOpcode = [](Instruction::BinaryOps BinOpcode) { @@ -1394,14 +1386,6 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) { } } - // (X >>u C1) >>u C --> X >>u (C1 + C) - if (match(Op0, m_LShr(m_Value(X), m_APInt(C1)))) { - // Oversized shifts are simplified to zero in InstSimplify. - unsigned AmtSum = ShAmtC + C1->getZExtValue(); - if (AmtSum < BitWidth) - return BinaryOperator::CreateLShr(X, ConstantInt::get(Ty, AmtSum)); - } - Instruction *TruncSrc; if (match(Op0, m_OneUse(m_Trunc(m_Instruction(TruncSrc)))) && match(TruncSrc, m_LShr(m_Value(X), m_APInt(C1)))) { -- GitLab From 9b0651f5ae6510577302ea527b2cc79e80ec9ccc Mon Sep 17 00:00:00 2001 From: martinboehme Date: Thu, 25 Apr 2024 09:22:14 +0200 Subject: [PATCH 062/733] [clang][dataflow] Don't propagate result objects in nested declarations. (#89903) Trying to do so can cause crashes -- see newly added test and the comments in the fix. --- .../FlowSensitive/DataflowEnvironment.cpp | 12 ++++++++++ .../Analysis/FlowSensitive/TransferTest.cpp | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 3cb656adcbdc..636d23020939 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -333,6 +333,18 @@ public: } } + bool TraverseDecl(Decl *D) { + // Don't traverse nested record or function declarations. + // - We won't be analyzing code contained in these anyway + // - We don't model fields that are used only in these nested declaration, + // so trying to propagate a result object to initializers of such fields + // would cause an error. + if (isa_and_nonnull(D) || isa_and_nonnull(D)) + return true; + + return RecursiveASTVisitor::TraverseDecl(D); + } + bool TraverseBindingDecl(BindingDecl *BD) { // `RecursiveASTVisitor` doesn't traverse holding variables for // `BindingDecl`s by itself, so we need to tell it to. diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 215e208615ac..5c7c39e52612 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -3309,6 +3309,28 @@ TEST(TransferTest, ResultObjectLocationPropagatesThroughConditionalOperator) { }); } +TEST(TransferTest, ResultObjectLocationDontVisitNestedRecordDecl) { + // This is a crash repro. + // We used to crash because when propagating result objects, we would visit + // nested record and function declarations, but we don't model fields used + // only in these. + std::string Code = R"( + struct S1 {}; + struct S2 { S1 s1; }; + void target() { + struct Nested { + void f() { + S2 s2 = { S1() }; + } + }; + } + )"; + runDataflow( + Code, + [](const llvm::StringMap> &Results, + ASTContext &ASTCtx) {}); +} + TEST(TransferTest, StaticCast) { std::string Code = R"( void target(int Foo) { -- GitLab From b9208ce318907b1a5ea4ad0d2aa4414dfba0616c Mon Sep 17 00:00:00 2001 From: martinboehme Date: Thu, 25 Apr 2024 09:24:08 +0200 Subject: [PATCH 063/733] [clang][dataflow] Crash fix for `widenDistinctValues()`. (#89895) We used to crash if the previous iteration contained a `BoolValue` and the current iteration contained an `IntegerValue`. The accompanying test sets up this situation -- see comments there for details. While I'm here, clean up the tests for integral casts to use the test helpers we have available now. I was looking at these tests to understand how we handle integral casts, and the test helpers make the tests easier to read. --- .../FlowSensitive/DataflowEnvironment.cpp | 13 ++-- .../Analysis/FlowSensitive/TransferTest.cpp | 65 +++++++++---------- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 636d23020939..d79e73440289 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -157,7 +157,13 @@ static WidenResult widenDistinctValues(QualType Type, Value &Prev, Value &Current, Environment &CurrentEnv, Environment::ValueModel &Model) { // Boolean-model widening. - if (auto *PrevBool = dyn_cast(&Prev)) { + if (isa(Prev) && isa(Current)) { + // FIXME: Checking both values should be unnecessary, but we can currently + // end up with `BoolValue`s in integer-typed variables. See comment in + // `joinDistinctValues()` for details. + auto &PrevBool = cast(Prev); + auto &CurBool = cast(Current); + if (isa(Prev)) // Safe to return `Prev` here, because Top is never dependent on the // environment. @@ -166,13 +172,12 @@ static WidenResult widenDistinctValues(QualType Type, Value &Prev, // We may need to widen to Top, but before we do so, check whether both // values are implied to be either true or false in the current environment. // In that case, we can simply return a literal instead. - auto &CurBool = cast(Current); - bool TruePrev = PrevEnv.proves(PrevBool->formula()); + bool TruePrev = PrevEnv.proves(PrevBool.formula()); bool TrueCur = CurrentEnv.proves(CurBool.formula()); if (TruePrev && TrueCur) return {&CurrentEnv.getBoolLiteralValue(true), LatticeEffect::Unchanged}; if (!TruePrev && !TrueCur && - PrevEnv.proves(PrevEnv.arena().makeNot(PrevBool->formula())) && + PrevEnv.proves(PrevEnv.arena().makeNot(PrevBool.formula())) && CurrentEnv.proves(CurrentEnv.arena().makeNot(CurBool.formula()))) return {&CurrentEnv.getBoolLiteralValue(false), LatticeEffect::Unchanged}; diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 5c7c39e52612..d204700919d3 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -3370,20 +3370,11 @@ TEST(TransferTest, IntegralCast) { Code, [](const llvm::StringMap> &Results, ASTContext &ASTCtx) { - ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); - const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); - ASSERT_THAT(FooDecl, NotNull()); - - const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); - ASSERT_THAT(BarDecl, NotNull()); - - const auto *FooVal = Env.getValue(*FooDecl); - const auto *BarVal = Env.getValue(*BarDecl); - EXPECT_TRUE(isa(FooVal)); - EXPECT_TRUE(isa(BarVal)); - EXPECT_EQ(FooVal, BarVal); + const auto &FooVal = getValueForDecl(ASTCtx, Env, "Foo"); + const auto &BarVal = getValueForDecl(ASTCtx, Env, "Bar"); + EXPECT_EQ(&FooVal, &BarVal); }); } @@ -3398,17 +3389,10 @@ TEST(TransferTest, IntegraltoBooleanCast) { Code, [](const llvm::StringMap> &Results, ASTContext &ASTCtx) { - ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); - const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); - ASSERT_THAT(FooDecl, NotNull()); - - const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); - ASSERT_THAT(BarDecl, NotNull()); - - const auto *FooVal = Env.getValue(*FooDecl); - const auto *BarVal = Env.getValue(*BarDecl); + const auto &FooVal = getValueForDecl(ASTCtx, Env, "Foo"); + const auto &BarVal = getValueForDecl(ASTCtx, Env, "Bar"); EXPECT_TRUE(isa(FooVal)); EXPECT_TRUE(isa(BarVal)); }); @@ -3426,23 +3410,38 @@ TEST(TransferTest, IntegralToBooleanCastFromBool) { Code, [](const llvm::StringMap> &Results, ASTContext &ASTCtx) { - ASSERT_THAT(Results.keys(), UnorderedElementsAre("p")); const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); - const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo"); - ASSERT_THAT(FooDecl, NotNull()); - - const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar"); - ASSERT_THAT(BarDecl, NotNull()); - - const auto *FooVal = Env.getValue(*FooDecl); - const auto *BarVal = Env.getValue(*BarDecl); - EXPECT_TRUE(isa(FooVal)); - EXPECT_TRUE(isa(BarVal)); - EXPECT_EQ(FooVal, BarVal); + const auto &FooVal = getValueForDecl(ASTCtx, Env, "Foo"); + const auto &BarVal = getValueForDecl(ASTCtx, Env, "Bar"); + EXPECT_EQ(&FooVal, &BarVal); }); } +TEST(TransferTest, WidenBoolValueInIntegerVariable) { + // This is a crash repro. + // This test sets up a case where we perform widening on an integer variable + // that contains a `BoolValue` for the previous iteration and an + // `IntegerValue` for the current iteration. We used to crash on this because + // `widenDistinctValues()` assumed that if the previous iteration had a + // `BoolValue`, the current iteration would too. + // FIXME: The real fix here is to make sure we never store `BoolValue`s in + // integer variables; see also the comment in `widenDistinctValues()`. + std::string Code = R"cc( + struct S { + int i; + S *next; + }; + void target(S *s) { + for (; s; s = s->next) + s->i = false; + } + )cc"; + runDataflow(Code, + [](const llvm::StringMap> &, + ASTContext &) {}); +} + TEST(TransferTest, NullToPointerCast) { std::string Code = R"( using my_nullptr_t = decltype(nullptr); -- GitLab From ed6e6afd5938e7d04862eb5ae2d09eb723663f25 Mon Sep 17 00:00:00 2001 From: Hans Date: Thu, 25 Apr 2024 09:27:01 +0200 Subject: [PATCH 064/733] [coro] Merge two almost identical tests (#89928) llvm/test/Transforms/Coroutines/coro-split-musttail10.ll and coro-split-musttail11.ll were the same except for the triple. Also add a requires clause. --- .../Coroutines/coro-split-musttail10.ll | 11 ++-- .../Coroutines/coro-split-musttail11.ll | 55 ------------------- 2 files changed, 7 insertions(+), 59 deletions(-) delete mode 100644 llvm/test/Transforms/Coroutines/coro-split-musttail11.ll diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail10.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail10.ll index cdd58b2a084f..3e91b79c10f7 100644 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail10.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail10.ll @@ -1,9 +1,12 @@ ; Tests that we would convert coro.resume to a musttail call if the target is -; Wasm64 with tail-call support. -; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s +; Wasm64 or Wasm32 with tail-call support. +; REQUIRES: webassembly-registered-target -target triple = "wasm64-unknown-unknown" +; RUN: opt -mtriple=wasm64-unknown-unknown < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s +; RUN: opt -mtriple=wasm64-unknown-unknown < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s + +; RUN: opt -mtriple=wasm32-unknown-unknown < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s +; RUN: opt -mtriple=wasm32-unknown-unknown < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s define void @f() #0 { entry: diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail11.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail11.ll deleted file mode 100644 index da5d868280e9..000000000000 --- a/llvm/test/Transforms/Coroutines/coro-split-musttail11.ll +++ /dev/null @@ -1,55 +0,0 @@ -; Tests that we would convert coro.resume to a musttail call if the target is -; Wasm32 with tail-call support. -; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -target triple = "wasm32-unknown-unknown" - -define void @f() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %addr1 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr1(ptr null) - - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - switch i8 %suspend, label %exit [ - i8 0, label %await.ready - i8 1, label %exit - ] -await.ready: - %save2 = call token @llvm.coro.save(ptr null) - %addr2 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr2(ptr null) - - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %exit - i8 1, label %exit - ] -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; CHECK: musttail call - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) - -attributes #0 = { presplitcoroutine "target-features"="+tail-call" } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } -- GitLab From 08949464ac4de9bac2a415fb3c0963060936ec17 Mon Sep 17 00:00:00 2001 From: Hans Date: Thu, 25 Apr 2024 09:35:48 +0200 Subject: [PATCH 065/733] [coro][pgo] Remove redundant coroutine test files (#89620) Each of these is a copy of a test under Transforms/Coroutines/ The PGO functionality is already covered by multiple runlines (pgo and no pgo) in the original files, so the copies add no new coverage, only maintenance problems. --- .../Coro/coro-split-musttail.ll | 63 ---------- .../Coro/coro-split-musttail1.ll | 97 --------------- .../Coro/coro-split-musttail10.ll | 55 --------- .../Coro/coro-split-musttail11.ll | 55 --------- .../Coro/coro-split-musttail12.ll | 85 ------------- .../Coro/coro-split-musttail13.ll | 76 ------------ .../Coro/coro-split-musttail2.ll | 68 ----------- .../Coro/coro-split-musttail3.ll | 91 -------------- .../Coro/coro-split-musttail4.ll | 66 ---------- .../Coro/coro-split-musttail5.ll | 63 ---------- .../Coro/coro-split-musttail6.ll | 112 ----------------- .../Coro/coro-split-musttail7.ll | 115 ------------------ 12 files changed, 946 deletions(-) delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail1.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail10.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail11.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail12.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail13.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail2.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail3.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail4.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail5.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail6.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail7.ll diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail.ll deleted file mode 100644 index a7321833d748..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail.ll +++ /dev/null @@ -1,63 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -define void @f() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %addr1 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr1(ptr null) - - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - switch i8 %suspend, label %exit [ - i8 0, label %await.ready - i8 1, label %exit - ] -await.ready: - %save2 = call token @llvm.coro.save(ptr null) - %addr2 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr2(ptr null) - - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %exit - i8 1, label %exit - ] -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; Verify that in the initial function resume is not marked with musttail. -; CHECK-LABEL: @f( -; CHECK: %[[addr1:.+]] = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) -; CHECK-NOT: musttail call fastcc void %[[addr1]](ptr null) - -; Verify that in the resume part resume call is marked with musttail. -; CHECK-LABEL: @f.resume( -; CHECK: %[[addr2:.+]] = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) -; CHECK: call void @llvm.instrprof -; CHECK-NEXT: musttail call fastcc void %[[addr2]](ptr null) -; CHECK-NEXT: ret void - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail1.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail1.ll deleted file mode 100644 index 6098dee9a580..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail1.ll +++ /dev/null @@ -1,97 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -define void @f() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %addr1 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr1(ptr null) - - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - switch i8 %suspend, label %exit [ - i8 0, label %await.suspend - i8 1, label %exit - ] -await.suspend: - %save2 = call token @llvm.coro.save(ptr null) - %br0 = call i8 @switch_result() - switch i8 %br0, label %unreach [ - i8 0, label %await.resume3 - i8 1, label %await.resume1 - i8 2, label %await.resume2 - ] -await.resume1: - %hdl = call ptr @g() - %addr2 = call ptr @llvm.coro.subfn.addr(ptr %hdl, i8 0) - call fastcc void %addr2(ptr %hdl) - br label %final.suspend -await.resume2: - %hdl2 = call ptr @h() - %addr3 = call ptr @llvm.coro.subfn.addr(ptr %hdl2, i8 0) - call fastcc void %addr3(ptr %hdl2) - br label %final.suspend -await.resume3: - %addr4 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr4(ptr null) - br label %final.suspend -final.suspend: - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %pre.exit - i8 1, label %exit - ] -pre.exit: - br label %exit -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -unreach: - unreachable -} - -; Verify that in the initial function resume is not marked with musttail. -; CHECK-LABEL: @f( -; CHECK: %[[addr1:.+]] = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) -; CHECK-NOT: musttail call fastcc void %[[addr1]](ptr null) - -; Verify that in the resume part resume call is marked with musttail. -; CHECK-LABEL: @f.resume( -; CHECK: %[[hdl:.+]] = call ptr @g() -; CHECK-NEXT: %[[addr2:.+]] = call ptr @llvm.coro.subfn.addr(ptr %[[hdl]], i8 0) -; CHECK: musttail call fastcc void %[[addr2]](ptr %[[hdl]]) -; CHECK-NEXT: ret void -; CHECK: %[[hdl2:.+]] = call ptr @h() -; CHECK-NEXT: %[[addr3:.+]] = call ptr @llvm.coro.subfn.addr(ptr %[[hdl2]], i8 0) -; CHECK: musttail call fastcc void %[[addr3]](ptr %[[hdl2]]) -; CHECK-NEXT: ret void -; CHECK: %[[addr4:.+]] = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) -; CHECK: musttail call fastcc void %[[addr4]](ptr null) -; CHECK-NEXT: ret void - - - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) -declare i8 @switch_result() -declare ptr @g() -declare ptr @h() - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail10.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail10.ll deleted file mode 100644 index f43b10ebf42e..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail10.ll +++ /dev/null @@ -1,55 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -target triple = "wasm64-unknown-unknown" - -define void @f() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %addr1 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr1(ptr null) - - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - switch i8 %suspend, label %exit [ - i8 0, label %await.ready - i8 1, label %exit - ] -await.ready: - %save2 = call token @llvm.coro.save(ptr null) - %addr2 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr2(ptr null) - - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %exit - i8 1, label %exit - ] -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; CHECK: musttail call - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) - -attributes #0 = { presplitcoroutine "target-features"="+tail-call" } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail11.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail11.ll deleted file mode 100644 index fc5bb9a1b20b..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail11.ll +++ /dev/null @@ -1,55 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -target triple = "wasm32-unknown-unknown" - -define void @f() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %addr1 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr1(ptr null) - - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - switch i8 %suspend, label %exit [ - i8 0, label %await.ready - i8 1, label %exit - ] -await.ready: - %save2 = call token @llvm.coro.save(ptr null) - %addr2 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr2(ptr null) - - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %exit - i8 1, label %exit - ] -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; CHECK: musttail call - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) - -attributes #0 = { presplitcoroutine "target-features"="+tail-call" } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail12.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail12.ll deleted file mode 100644 index 634d0106a2e6..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail12.ll +++ /dev/null @@ -1,85 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -declare void @fakeresume1(ptr) -declare void @print() - -define void @f(i1 %cond) #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - - %init_suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - switch i8 %init_suspend, label %coro.end [ - i8 0, label %await.ready - i8 1, label %coro.end - ] -await.ready: - %save2 = call token @llvm.coro.save(ptr null) - br i1 %cond, label %then, label %else - -then: - call fastcc void @fakeresume1(ptr align 8 null) - br label %merge - -else: - br label %merge - -merge: - %v0 = phi i1 [0, %then], [1, %else] - br label %compare - -compare: - %cond.cmp = icmp eq i1 %v0, 0 - br i1 %cond.cmp, label %ready, label %prepare - -prepare: - call void @print() - br label %ready - -ready: - %suspend = call i8 @llvm.coro.suspend(token %save2, i1 true) - %switch = icmp ult i8 %suspend, 2 - br i1 %switch, label %cleanup, label %coro.end - -cleanup: - %free.handle = call ptr @llvm.coro.free(token %id, ptr %vFrame) - %.not = icmp eq ptr %free.handle, null - br i1 %.not, label %coro.end, label %coro.free - -coro.free: - call void @delete(ptr nonnull %free.handle) #2 - br label %coro.end - -coro.end: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; CHECK-LABEL: @f.resume( -; CHECK-NOT: } -; CHECK: call void @print() - - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) -declare void @delete(ptr nonnull) #2 - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail13.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail13.ll deleted file mode 100644 index 2f9a14c90107..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail13.ll +++ /dev/null @@ -1,76 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -declare void @fakeresume1(ptr) -declare void @may_throw(ptr) -declare void @print() - -define void @f(i1 %cond) #0 personality i32 3 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - - %init_suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - switch i8 %init_suspend, label %coro.end [ - i8 0, label %await.ready - i8 1, label %coro.end - ] -await.ready: - call fastcc void @fakeresume1(ptr align 8 null) - invoke void @may_throw(ptr null) - to label %ready unwind label %lpad - -ready: - %save2 = call token @llvm.coro.save(ptr null) - %suspend = call i8 @llvm.coro.suspend(token %save2, i1 true) - %switch = icmp ult i8 %suspend, 2 - br i1 %switch, label %cleanup, label %coro.end - -cleanup: - %free.handle = call ptr @llvm.coro.free(token %id, ptr %vFrame) - %.not = icmp eq ptr %free.handle, null - br i1 %.not, label %coro.end, label %coro.free - -lpad: - %lpval = landingpad { ptr, i32 } - cleanup - - %need.resume = call i1 @llvm.coro.end(ptr null, i1 true, token none) - resume { ptr, i32 } %lpval - -coro.free: - call void @delete(ptr nonnull %free.handle) #2 - br label %coro.end - -coro.end: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; CHECK-LABEL: @f.resume( -; CHECK-NOT: musttail call fastcc void @fakeresume1( -; CHECK: } - - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) -declare void @delete(ptr nonnull) #2 - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail2.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail2.ll deleted file mode 100644 index 61b61a200e70..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail2.ll +++ /dev/null @@ -1,68 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -define void @fakeresume1(ptr) { -entry: - ret void; -} - -define void @fakeresume2(ptr align 8) { -entry: - ret void; -} - -define void @g() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - call fastcc void @fakeresume1(ptr null) - - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - switch i8 %suspend, label %exit [ - i8 0, label %await.ready - i8 1, label %exit - ] -await.ready: - %save2 = call token @llvm.coro.save(ptr null) - call fastcc void @fakeresume2(ptr align 8 null) - - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %exit - i8 1, label %exit - ] -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; Verify that in the initial function resume is not marked with musttail. -; CHECK-LABEL: @g( -; CHECK-NOT: musttail call fastcc void @fakeresume1(ptr null) - -; Verify that in the resume part resume call is marked with musttail. -; CHECK-LABEL: @g.resume( -; CHECK: musttail call fastcc void @fakeresume2(ptr align 8 null) -; CHECK-NEXT: ret void - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail3.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail3.ll deleted file mode 100644 index 82176b8085e6..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail3.ll +++ /dev/null @@ -1,91 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -define void @f() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %addr1 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr1(ptr null) - - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - %cmp = icmp eq i8 %suspend, 0 - br i1 %cmp, label %await.suspend, label %exit -await.suspend: - %save2 = call token @llvm.coro.save(ptr null) - %br0 = call i8 @switch_result() - switch i8 %br0, label %unreach [ - i8 0, label %await.resume3 - i8 1, label %await.resume1 - i8 2, label %await.resume2 - ] -await.resume1: - %hdl = call ptr @g() - %addr2 = call ptr @llvm.coro.subfn.addr(ptr %hdl, i8 0) - call fastcc void %addr2(ptr %hdl) - br label %final.suspend -await.resume2: - %hdl2 = call ptr @h() - %addr3 = call ptr @llvm.coro.subfn.addr(ptr %hdl2, i8 0) - call fastcc void %addr3(ptr %hdl2) - br label %final.suspend -await.resume3: - %addr4 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) - call fastcc void %addr4(ptr null) - br label %final.suspend -final.suspend: - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - %cmp2 = icmp eq i8 %suspend2, 0 - br i1 %cmp2, label %pre.exit, label %exit -pre.exit: - br label %exit -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -unreach: - unreachable -} - -; Verify that in the initial function resume is not marked with musttail. -; CHECK-LABEL: @f( -; CHECK: %[[addr1:.+]] = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) -; CHECK-NOT: musttail call fastcc void %[[addr1]](ptr null) - -; Verify that in the resume part resume call is marked with musttail. -; CHECK-LABEL: @f.resume( -; CHECK: %[[hdl:.+]] = call ptr @g() -; CHECK-NEXT: %[[addr2:.+]] = call ptr @llvm.coro.subfn.addr(ptr %[[hdl]], i8 0) -; CHECK: musttail call fastcc void %[[addr2]](ptr %[[hdl]]) -; CHECK-NEXT: ret void -; CHECK: %[[hdl2:.+]] = call ptr @h() -; CHECK-NEXT: %[[addr3:.+]] = call ptr @llvm.coro.subfn.addr(ptr %[[hdl2]], i8 0) -; CHECK: musttail call fastcc void %[[addr3]](ptr %[[hdl2]]) -; CHECK-NEXT: ret void -; CHECK: %[[addr4:.+]] = call ptr @llvm.coro.subfn.addr(ptr null, i8 0) -; CHECK: musttail call fastcc void %[[addr4]](ptr null) -; CHECK-NEXT: ret void - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) -declare i8 @switch_result() -declare ptr @g() -declare ptr @h() - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail4.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail4.ll deleted file mode 100644 index be70fc4b51f1..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail4.ll +++ /dev/null @@ -1,66 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -define void @fakeresume1(ptr) { -entry: - ret void; -} - -define void @f() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - - %init_suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - switch i8 %init_suspend, label %coro.end [ - i8 0, label %await.ready - i8 1, label %coro.end - ] -await.ready: - %save2 = call token @llvm.coro.save(ptr null) - - call fastcc void @fakeresume1(ptr align 8 null) - %suspend = call i8 @llvm.coro.suspend(token %save2, i1 true) - %switch = icmp ult i8 %suspend, 2 - br i1 %switch, label %cleanup, label %coro.end - -cleanup: - %free.handle = call ptr @llvm.coro.free(token %id, ptr %vFrame) - %.not = icmp eq ptr %free.handle, null - br i1 %.not, label %coro.end, label %coro.free - -coro.free: - call void @delete(ptr nonnull %free.handle) #2 - br label %coro.end - -coro.end: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; CHECK-LABEL: @f.resume( -; CHECK: musttail call fastcc void @fakeresume1( -; CHECK-NEXT: ret void - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) -declare void @delete(ptr nonnull) #2 - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail5.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail5.ll deleted file mode 100644 index 3e5bddd8e131..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail5.ll +++ /dev/null @@ -1,63 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -declare void @fakeresume1(ptr align 8) - -define void @g() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %alloc.var = alloca i8 - call void @llvm.lifetime.start.p0(i64 1, ptr %alloc.var) - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - - switch i8 %suspend, label %exit [ - i8 0, label %await.suspend - i8 1, label %exit - ] -await.suspend: - %save2 = call token @llvm.coro.save(ptr null) - call fastcc void @fakeresume1(ptr align 8 null) - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %await.ready - i8 1, label %exit - ] -await.ready: - call void @consume(ptr %alloc.var) - call void @llvm.lifetime.end.p0(i64 1, ptr %alloc.var) - br label %exit -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; Verify that in the resume part resume call is marked with musttail. -; CHECK-LABEL: @g.resume( -; CHECK: musttail call fastcc void @fakeresume1(ptr align 8 null) -; CHECK-NEXT: ret void - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) -declare void @consume(ptr) -declare void @llvm.lifetime.start.p0(i64, ptr nocapture) -declare void @llvm.lifetime.end.p0(i64, ptr nocapture) - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail6.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail6.ll deleted file mode 100644 index 4359d5305d4d..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail6.ll +++ /dev/null @@ -1,112 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -declare void @fakeresume1(ptr align 8) - -define void @g() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %alloc.var = alloca i64 - call void @llvm.lifetime.start.p0(i64 1, ptr %alloc.var) - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - - switch i8 %suspend, label %exit [ - i8 0, label %await.suspend - i8 1, label %exit - ] -await.suspend: - %save2 = call token @llvm.coro.save(ptr null) - call fastcc void @fakeresume1(ptr align 8 null) - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %await.ready - i8 1, label %exit - ] -await.ready: - call void @consume(ptr %alloc.var) - call void @llvm.lifetime.end.p0(i64 1, ptr %alloc.var) - br label %exit -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; Verify that in the resume part resume call is marked with musttail. -; CHECK-LABEL: @g.resume( -; CHECK: musttail call fastcc void @fakeresume1(ptr align 8 null) -; CHECK-NEXT: ret void - -; It has a cleanup bb. -define void @f() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %alloc.var = alloca i64 - call void @llvm.lifetime.start.p0(i64 1, ptr %alloc.var) - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - - switch i8 %suspend, label %exit [ - i8 0, label %await.suspend - i8 1, label %exit - ] -await.suspend: - %save2 = call token @llvm.coro.save(ptr null) - call fastcc void @fakeresume1(ptr align 8 null) - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %await.ready - i8 1, label %cleanup - ] -await.ready: - call void @consume(ptr %alloc.var) - call void @llvm.lifetime.end.p0(i64 1, ptr %alloc.var) - br label %exit - -cleanup: - %free.handle = call ptr @llvm.coro.free(token %id, ptr %vFrame) - %.not = icmp eq ptr %free.handle, null - br i1 %.not, label %exit, label %coro.free - -coro.free: - call void @delete(ptr nonnull %free.handle) #2 - br label %exit - -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; Verify that in the resume part resume call is marked with musttail. -; CHECK-LABEL: @f.resume( -; CHECK: musttail call fastcc void @fakeresume1(ptr align 8 null) -; CHECK-NEXT: ret void - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) -declare void @delete(ptr nonnull) #2 -declare void @consume(ptr) -declare void @llvm.lifetime.start.p0(i64, ptr nocapture) -declare void @llvm.lifetime.end.p0(i64, ptr nocapture) - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } diff --git a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail7.ll b/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail7.ll deleted file mode 100644 index 2a14be0f9218..000000000000 --- a/llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail7.ll +++ /dev/null @@ -1,115 +0,0 @@ -; Tests that instrumentation doesn't interfere with lowering (coro-split). -; It should convert coro.resume followed by a suspend to a musttail call. - -; The difference between this and coro-split-musttail5.ll and coro-split-musttail5.ll -; is that this contains dead instruction generated during the transformation, -; which makes the optimization harder. -; RUN: opt < %s -passes='pgo-instr-gen,cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s - -declare void @fakeresume1(ptr align 8) - -define void @g() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %alloc.var = alloca i64 - call void @llvm.lifetime.start.p0(i64 1, ptr %alloc.var) - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - - switch i8 %suspend, label %exit [ - i8 0, label %await.suspend - i8 1, label %exit - ] -await.suspend: - %save2 = call token @llvm.coro.save(ptr null) - call fastcc void @fakeresume1(ptr align 8 null) - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %await.ready - i8 1, label %exit - ] -await.ready: - call void @consume(ptr %alloc.var) - call void @llvm.lifetime.end.p0(i64 1, ptr %alloc.var) - br label %exit -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; Verify that in the resume part resume call is marked with musttail. -; CHECK-LABEL: @g.resume( -; CHECK: musttail call fastcc void @fakeresume1(ptr align 8 null) -; CHECK-NEXT: ret void - -; It has a cleanup bb. -define void @f() #0 { -entry: - %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) - %alloc = call ptr @malloc(i64 16) #3 - %alloc.var = alloca i64 - call void @llvm.lifetime.start.p0(i64 1, ptr %alloc.var) - %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc) - - %save = call token @llvm.coro.save(ptr null) - %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) - - switch i8 %suspend, label %exit [ - i8 0, label %await.suspend - i8 1, label %exit - ] -await.suspend: - %save2 = call token @llvm.coro.save(ptr null) - call fastcc void @fakeresume1(ptr align 8 null) - %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) - switch i8 %suspend2, label %exit [ - i8 0, label %await.ready - i8 1, label %cleanup - ] -await.ready: - call void @consume(ptr %alloc.var) - call void @llvm.lifetime.end.p0(i64 1, ptr %alloc.var) - br label %exit - -cleanup: - %free.handle = call ptr @llvm.coro.free(token %id, ptr %vFrame) - %.not = icmp eq ptr %free.handle, null - br i1 %.not, label %exit, label %coro.free - -coro.free: - call void @delete(ptr nonnull %free.handle) #2 - br label %exit - -exit: - call i1 @llvm.coro.end(ptr null, i1 false, token none) - ret void -} - -; Verify that in the resume part resume call is marked with musttail. -; CHECK-LABEL: @f.resume( -; CHECK: musttail call fastcc void @fakeresume1(ptr align 8 null) -; CHECK-NEXT: ret void - -declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 -declare i1 @llvm.coro.alloc(token) #2 -declare i64 @llvm.coro.size.i64() #3 -declare ptr @llvm.coro.begin(token, ptr writeonly) #2 -declare token @llvm.coro.save(ptr) #2 -declare ptr @llvm.coro.frame() #3 -declare i8 @llvm.coro.suspend(token, i1) #2 -declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 -declare i1 @llvm.coro.end(ptr, i1, token) #2 -declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #1 -declare ptr @malloc(i64) -declare void @delete(ptr nonnull) #2 -declare void @consume(ptr) -declare void @llvm.lifetime.start.p0(i64, ptr nocapture) -declare void @llvm.lifetime.end.p0(i64, ptr nocapture) - -attributes #0 = { presplitcoroutine } -attributes #1 = { argmemonly nounwind readonly } -attributes #2 = { nounwind } -attributes #3 = { nounwind readnone } -- GitLab From 5e767bd7d16dcdfc1ad8b32ba399f969dd940f57 Mon Sep 17 00:00:00 2001 From: "Daniel M. Katz" Date: Thu, 25 Apr 2024 03:41:25 -0400 Subject: [PATCH 066/733] Push immediate function context while transforming lambdas in templates. (#89702) The following program is [accepted](https://godbolt.org/z/oEc34Trh4) by Clang, EDG, and MSVC, but rejected by Clang: ```cpp #include consteval auto fn() { return std::vector {1,2,3}; } template void fn2() { (void)[]() consteval { for (auto e : fn()) {} }; } void caller() { fn2(); } ``` The stated diagnostic is: ```cpp :8:21: error: call to consteval function 'fn' is not a constant expression 8 | for (auto e : fn()) {} ``` The body of the lambda should be evaluated as within an immediate function context when the lambda is marked as `consteval`. Co-authored-by: cor3ntin --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/TreeTransform.h | 2 ++ clang/test/SemaCXX/cxx2a-consteval.cpp | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7bea43ec64f0..0bad03eda8cb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -564,6 +564,8 @@ Bug Fixes to C++ Support - Fixed a crash when trying to evaluate a user-defined ``static_assert`` message whose ``size()`` function returns a large or negative value. Fixes (#GH89407). - Fixed a use-after-free bug in parsing of type constraints with default arguments that involve lambdas. (#GH67235) +- Fixed bug in which the body of a consteval lambda within a template was not parsed as within an + immediate function context. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 9404be5a46f3..1d30ba31e179 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -14186,6 +14186,8 @@ TreeTransform::TransformLambdaExpr(LambdaExpr *E) { // FIXME: Sema's lambda-building mechanism expects us to push an expression // evaluation context even if we're not transforming the function body. getSema().PushExpressionEvaluationContext( + E->getCallOperator()->isConsteval() ? + Sema::ExpressionEvaluationContext::ImmediateFunctionContext : Sema::ExpressionEvaluationContext::PotentiallyEvaluated); Sema::CodeSynthesisContext C; diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 192621225a54..e19807437207 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -260,6 +260,26 @@ int(*test)(int) = l1; } +namespace consteval_lambda_in_template { +struct S { + int *value; + constexpr S(int v) : value(new int {v}) {} + constexpr ~S() { delete value; } +}; +consteval S fn() { return S(5); } + +template +void fn2() { + (void)[]() consteval -> int { + return *(fn().value); // OK, immediate context + }; +} + +void caller() { + fn2(); +} +} + namespace std { template struct remove_reference { using type = T; }; -- GitLab From 51f6570eba69b7030f2845e30b7973bd9ac6c522 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Thu, 25 Apr 2024 08:49:57 +0100 Subject: [PATCH 067/733] [lldb][Docs] Convert platform packets doc to Markdown (#89913) As before, script did most of the work, hand edits after that. There's a lot more we can do dedupe this and the packets doc, this will come in a follow up PR. --- lldb/docs/index.rst | 1 + lldb/docs/lldb-platform-packets.txt | 451 ------------------- lldb/docs/resources/lldbplatformpackets.md | 484 +++++++++++++++++++++ 3 files changed, 485 insertions(+), 451 deletions(-) delete mode 100644 lldb/docs/lldb-platform-packets.txt create mode 100644 lldb/docs/resources/lldbplatformpackets.md diff --git a/lldb/docs/index.rst b/lldb/docs/index.rst index 6906566ea55e..7a27f6914fa8 100644 --- a/lldb/docs/index.rst +++ b/lldb/docs/index.rst @@ -158,6 +158,7 @@ interesting areas to contribute to lldb. resources/dataformatters resources/extensions resources/lldbgdbremote + resources/lldbplatformpackets resources/caveats resources/projects Public C++ API diff --git a/lldb/docs/lldb-platform-packets.txt b/lldb/docs/lldb-platform-packets.txt deleted file mode 100644 index 4cf575e5ee8a..000000000000 --- a/lldb/docs/lldb-platform-packets.txt +++ /dev/null @@ -1,451 +0,0 @@ -Here is a brief overview of the packets that an lldb platform server -needs to implement for the lldb testsuite to be run on a remote -target device/system. - -These are almost all lldb extensions to the gdb-remote serial -protocol. Many of the vFile: packets are described to the "Host -I/O Packets" detailed in the gdb-remote protocol documentation, -although the lldb platform extensions include packets that are not -defined there (vFile:size:, vFile:mode:, vFile:symlink, vFile:chmod:). -Most importantly, the flags that lldb passes to vFile:open: are -incompatible with the flags that gdb specifies. - - -//---------------------------------------------------------------------- -// QStartNoAckMode -// -// BRIEF -// A request to stop sending ACK packets for each properly formatted packet. -// -// EXAMPLE -// A platform session will typically start like this: -// -// receive: +$QStartNoAckMode#b0 -// send: + <-- ACKing the properly formatted QStartNoAckMode packet -// send: $OK#9a -// receive: + <-- Our OK packet getting ACKed -// -// ACK mode is now disabled. - -//---------------------------------------------------------------------- -// qHostInfo -// -// BRIEF -// Describe the hardware and OS of the target system -// -// EXAMPLE -// -// receive: qHostInfo -// send: cputype:16777228;cpusubtype:1;ostype:ios;watchpoint_exceptions_received:before;os_version:12.1;vendor:apple;default_packet_timeout:5; -// -// All numbers are base 10, os_version is a string that will be parsed as major.minor.patch. - -//---------------------------------------------------------------------- -// qModuleInfo -// -// BRIEF -// Report information about a binary on the target system -// -// EXAMPLE -// receive: qModuleInfo:2f62696e2f6c73; -// -// FIXME finish this packet description, v. GDBRemoteCommunicationServerCommon::Handle_qModuleInfo - - -//---------------------------------------------------------------------- -// qGetWorkingDir -// -// BRIEF -// Get the current working directory of the platform stub in -// ASCII hex encoding. -// -// EXAMPLE -// -// receive: qGetWorkingDir -// send: 2f4170706c65496e7465726e616c2f6c6c64622f73657474696e67732f342f5465737453657474696e67732e746573745f646973617373656d626c65725f73657474696e6773 - - - -//---------------------------------------------------------------------- -// QSetWorkingDir: -// -// BRIEF -// Set the current working directory of the platform stub in -// ASCII hex encoding. -// -// EXAMPLE -// -// receive: QSetWorkingDir:2f4170706c65496e7465726e616c2f6c6c64622f73657474696e67732f342f5465737453657474696e67732e746573745f646973617373656d626c65725f73657474696e6773 -// send: OK - -//---------------------------------------------------------------------- -// qPlatform_mkdir: -// -// BRIEF -// Create a directory on the target system. -// -// EXAMPLE -// -// receive: qPlatform_mkdir:000001fd,2f746d702f6131 -// send: F0 -// -// request packet has the fields: -// 1. mode bits in base 16 -// 2. file path in ascii-hex encoding -// -// response is F followed by the return value of the mkdir() call, -// base 16 encoded. - -//---------------------------------------------------------------------- -// qPlatform_shell: -// -// BRIEF -// Run a shell command on the target system, return the output. -// -// EXAMPLE -// -// receive: qPlatform_shell:6c73202f746d702f,0000000a -// send: F,0,0, -// -// request packet has the fields: -// 1. shell command ascii-hex encoded -// 2. timeout -// 3. {optional} working directory ascii-hex encoded -// -// Response is F followed by the return value of the command (base 16), -// followed by another number, followed by the output of the command -/ in binary-escaped-data encoding. - -//---------------------------------------------------------------------- -// qLaunchGDBServer -// -// BRIEF -// Start a gdbserver process (gdbserver, debugserver, lldb-server) -// on the target system. -// -// EXAMPLE -// -// receive: qLaunchGDBServer;host:; -// send: pid:1337;port:43001; -// -// request packet hostname field is not ascii-hex encoded. Hostnames -// don't have $ or # characters in them. -// -// response to the packet is the pid of the newly launched gdbserver, -// and the port it is listening for a connection on. -// -// When the testsuite is running, lldb may use the pid to kill off a -// debugserver that doesn't seem to be responding, etc. - -//---------------------------------------------------------------------- -// qKillSpawnedProcess: -// -// BRIEF -// Kill a process running on the target system. -// -// EXAMPLE -// -// receive: qKillSpawnedProcess:1337 -// send: OK -// -// The request packet has the process ID in base 10. - -//---------------------------------------------------------------------- -// qProcessInfoPID: -// -// BRIEF -// Gather information about a process running on the target -// -// EXAMPLE -// -// receive: qProcessInfoPID:71964 -// send: pid:71964;name:612e6f7574; -// -// The request packet has the pid encoded in base 10. -// -// The reply has semicolon-separated name:value fields, two are -// shown here. pid is base 10 encoded. name is ascii hex encoded. -// lldb-server can reply with many additional fields, but I think -// this is enough for the testsuite. - -//---------------------------------------------------------------------- -// qfProcessInfo: -// -// BRIEF -// Search the process table for processes matching criteria, -// respond with them in multiple packets. -// -// EXAMPLE -// -// receive: qfProcessInfo:name_match:equals;name:6e6f70726f6365737365786973747377697468746869736e616d65; -// send: pid:3500;name:612e6f7574; -// -// The request packet has a criteria to search for, followed by -// a specific name. -// -// KEY VALUE DESCRIPTION -// =========== ======== ================================================ -// "name" ascii-hex An ASCII hex string that contains the name of -// the process that will be matched. -// "name_match" enum One of: "equals", "starts_with", "ends_with", -// "contains" or "regex" -// "pid" integer A string value containing the decimal process ID -// "parent_pid" integer A string value containing the decimal parent -// process ID -// "uid" integer A string value containing the decimal user ID -// "gid" integer A string value containing the decimal group ID -// "euid" integer A string value containing the decimal effective user ID -// "egid" integer A string value containing the decimal effective group ID -// "all_users" bool A boolean value that specifies if processes should -// be listed for all users, not just the user that the -// platform is running as -// "triple" ascii-hex An ASCII hex target triple string ("x86_64", -// "x86_64-apple-macosx", "armv7-apple-ios") -// -// If no criteria is given, qfProcessInfo will request a list of every process. -// -// The lldb testsuite currently only uses name_match:equals and the -// no-criteria mode to list every process. -// -// The response should include any information about the process that -// can be retrieved in semicolon-separated name:value fields. -// In this example, pid is base 10, name is ascii-hex encoded. -// The testsuite seems to only require these two. -// -// This packet only responds with one process. To get further matches to -// the search, qsProcessInfo should be sent. -// -// If no process match is found, Exx should be returned. -// -// Sample packet/response: -// send packet: $qfProcessInfo#00 -// read packet: $pid:60001;ppid:59948;uid:7746;gid:11;euid:7746;egid:11;name:6c6c6462;triple:7838365f36342d6170706c652d6d61636f7378;#00 -// send packet: $qsProcessInfo#00 -// read packet: $pid:59992;ppid:192;uid:7746;gid:11;euid:7746;egid:11;name:6d64776f726b6572;triple:7838365f36342d6170706c652d6d61636f7378;#00 -// send packet: $qsProcessInfo#00 -// read packet: $E04#00 - -//---------------------------------------------------------------------- -// qsProcessInfo -// -// BRIEF -// Return the next process info found by the most recent qfProcessInfo: -// packet. -// -// EXAMPLE -// -// Continues to return the results of the qfProcessInfo. Once all matches -// have been sent, Exx is returned to indicate end of matches. - -//---------------------------------------------------------------------- -// qPathComplete -// -// BRIEF -// Get a list of matched disk files/directories by passing a boolean flag -// and a partial path. -// -// EXAMPLE -// -// receive: qPathComplete:0,6d61696e -// send: M6d61696e2e637070 -// receive: qPathComplete:1,746573 -// send: M746573742f,74657374732f -// -// If the first argument is zero, the result should contain all -// files (including directories) starting with the given path. If the -// argument is one, the result should contain only directories. -// -// The result should be a comma-separated list of hex-encoded paths. -// Paths denoting a directory should end with a directory separator ('/' or '\'). - -//---------------------------------------------------------------------- -// vFile:size: -// -// BRIEF -// Get the size of a file on the target system, filename in ASCII hex. -// -// EXAMPLE -// -// receive: vFile:size:2f746d702f61 -// send: Fc008 -// -// response is "F" followed by the file size in base 16. -// "F-1,errno" with the errno if an error occurs, base 16. - - -//---------------------------------------------------------------------- -// vFile:mode: -// -// BRIEF -// Get the mode bits of a file on the target system, filename in ASCII hex. -// -// EXAMPLE -// -// receive: vFile:mode:2f746d702f61 -// send: F1ed -// -// response is "F" followed by the mode bits in base 16, this 0x1ed would -// correspond to 0755 in octal. -// "F-1,errno" with the errno if an error occurs, base 16. - -//---------------------------------------------------------------------- -// vFile:unlink: -// -// BRIEF -// Remove a file on the target system. -// -// EXAMPLE -// -// receive: vFile:unlink:2f746d702f61 -// send: F0 -// -// Argument is a file path in ascii-hex encoding. -// Response is "F" plus the return value of unlink(), base 16 encoding. -// Return value may optionally be followed by a comma and the base16 -// value of errno if unlink failed. - -//---------------------------------------------------------------------- -// vFile:symlink: -// -// BRIEF -// Create a symbolic link (symlink, soft-link) on the target system. -// -// EXAMPLE -// -// receive: vFile:symlink:, -// send: F0,0 -// -// Argument file paths are in ascii-hex encoding. -// Response is "F" plus the return value of symlink(), base 16 encoding, -// optionally followed by the value of errno if it failed, also base 16. - -//---------------------------------------------------------------------- -// vFile:chmod: -// qPlatform_chmod: -// -// BRIEF -// Change the permission mode bits on a file on the target -// -// EXAMPLE -// -// receive: vFile:chmod:180,2f746d702f61 -// send: F0 -// -// Arguments are the mode bits to set, base 16, and a file path in -// ascii-hex encoding. -// Response is "F" plus the return value of chmod(), base 16 encoding. -// -// I don't know why there are two packets for the same thing, v. -// vFile:chmod:. - -//---------------------------------------------------------------------- -// vFile:chmod: -// -// BRIEF -// Change the permission mode bits on a file on the target -// -// EXAMPLE -// -// receive: vFile:chmod:180,2f746d702f61 -// send: F0 -// -// Arguments are the mode bits to set, base 16, and a file path in -// ascii-hex encoding. -// Response is "F" plus the return value of chmod(), base 10 encoding. - - -//---------------------------------------------------------------------- -// vFile:open: -// -// BRIEF -// Open a file on the remote system and return the file descriptor of it. -// -// EXAMPLE -// -// receive: vFile:open:2f746d702f61,00000001,00000180 -// send: F8 -// -// request packet has the fields: -// 1. ASCII hex encoded filename -// 2. flags passed to the open call, base 16. -// Note that these are not the oflags that open(2) takes, but -// are the constant values in enum OpenOptions from lldb's File.h -// 3. mode bits, base 16 -// -// response is F followed by the opened file descriptor in base 16. -// "F-1,errno" with the errno if an error occurs, base 16. -// -//---------------------------------------------------------------------- -// vFile:close: -// -// BRIEF -// Close a previously opened file descriptor. -// -// EXAMPLE -// -// receive: vFile:close:7 -// send: F0 -// -// File descriptor is in base 16. -// "F-1,errno" with the errno if an error occurs, -// errno is base 16. - - -//---------------------------------------------------------------------- -// vFile:pread: -// -// BRIEF -// Read data from an opened file descriptor. -// -// EXAMPLE -// -// receive: vFile:pread:7,1024,0 -// send: F4;a'b\00 -// -// request packet has the fields: -// 1. file descriptor, base 16 -// 2. number of bytes to be read, base 16 -// 3. offset into file to start from, base 16 -// -// Response is F, followed by the number of bytes read (base 16), a -// semicolon, followed by the data in the binary-escaped-data encoding. - - -//---------------------------------------------------------------------- -// vFile:pwrite: -// -// BRIEF -// Write data to a previously opened file descriptor. -// -// EXAMPLE -// -// receive: vFile:pwrite:8,0,\cf\fa\ed\fe\0c\00\00 -// send: F1024 -// -// request packet has the fields: -// 1. file descriptor, base 16 -// 2. offset into file to start from, base 16 -// 3. binary-escaped-data to be written -// -// Response is F, followed by the number of bytes written (base 16) - - - - - -Finally, the platform must be able to launch processes so that debugserver -can attach to them. To do this, the following packets should be handled: - -QSetDisableASLR -QSetDetachOnError -QSetSTDOUT -QSetSTDERR -QSetSTDIN -QEnvironment -QEnvironmentHexEncoded -A -qLaunchSuccess -qProcessInfo - -Most of these are documented in the standard gdb-remote protocol -and/or the lldb-gdb-remote.txt documentation. diff --git a/lldb/docs/resources/lldbplatformpackets.md b/lldb/docs/resources/lldbplatformpackets.md new file mode 100644 index 000000000000..326dd5669f79 --- /dev/null +++ b/lldb/docs/resources/lldbplatformpackets.md @@ -0,0 +1,484 @@ +# LLDB Platform Packets + +Here is a brief overview of the packets that an lldb platform server +needs to implement for the lldb testsuite to be run on a remote +target device/system. + +These are almost all lldb extensions to the gdb-remote serial +protocol. Many of the `vFile:` packets are also described in the "Host +I/O Packets" detailed in the gdb-remote protocol documentation, +although the lldb platform extensions include packets that are not +defined there (`vFile:size:`, `vFile:mode:`, `vFile:symlink`, `vFile:chmod:`). + +Most importantly, the flags that lldb passes to `vFile:open:` are +incompatible with the flags that gdb specifies. + +## QStartNoAckMode + +### Brief + +A request to stop sending ACK packets for each properly formatted packet. + +### Example + +A platform session will typically start like this: +``` +receive: +$QStartNoAckMode#b0 +send: + <-- ACKing the properly formatted QStartNoAckMode packet +send: $OK#9a +receive: + <-- Our OK packet getting ACKed +``` + +ACK mode is now disabled. + +## qHostInfo + +### Brief + +Describe the hardware and OS of the target system + +### Example + +``` +receive: qHostInfo +send: cputype:16777228;cpusubtype:1;ostype:ios;watchpoint_exceptions_received:before;os_version:12.1;vendor:apple;default_packet_timeout:5; +``` + +All numbers are base 10, `os_version` is a string that will be parsed as major.minor.patch. + +## qModuleInfo + +### Brief + +Get information for a module by given module path and architecture. + +The response is: +* `(uuid|md5):...;triple:...;file_offset:...;file_size...;` or +* `EXX` - for any errors + +### Example + +``` +receive: qModuleInfo:2f62696e2f6c73; +``` + +## qGetWorkingDir + +### Brief + +Get the current working directory of the platform stub in +ASCII hex encoding. + +### Example + +``` +receive: qGetWorkingDir +send: 2f4170706c65496e7465726e616c2f6c6c64622f73657474696e67732f342f5465737453657474696e67732e746573745f646973617373656d626c65725f73657474696e6773 +``` + +## QSetWorkingDir + +### Brief + +Set the current working directory of the platform stub in +ASCII hex encoding. + +### Example + +``` +receive: QSetWorkingDir:2f4170706c65496e7465726e616c2f6c6c64622f73657474696e67732f342f5465737453657474696e67732e746573745f646973617373656d626c65725f73657474696e6773 +send: OK +``` + +## qPlatform_mkdir + +### Brief + +Create a directory on the target system. + +### Example + +``` +receive: qPlatform_mkdir:000001fd,2f746d702f6131 +send: F0 +``` + +request packet has the fields: + 1. mode bits in base 16 + 2. file path in ASCII hex encoding + +response is F followed by the return value of the `mkdir()` call, +base 16 encoded. + +## qPlatform_shell + +### Brief + +Run a shell command on the target system, return the output. + +### Example + +``` +receive: qPlatform_shell:6c73202f746d702f,0000000a +send: F,0,0, +``` + +request packet has the fields: + 1. shell command in ASCII hex encoding + 2. timeout + 3. working directory in ASCII hex encoding (optional) + +Response is `F` followed by the return value of the command (base 16), +followed by another number, followed by the output of the command +in binary-escaped-data encoding. + +## qLaunchGDBServer + +### Brief + +Start a gdbserver process (`gdbserver`, `debugserver`, `lldb-server`) +on the target system. + +### Example + +``` +receive: qLaunchGDBServer;host:; +send: pid:1337;port:43001; +``` + +Request packet hostname field is not ASCII hex encoded. Hostnames +do not have `$` or `#` characters in them. + +Response to the packet is the pid of the newly launched gdbserver, +and the port it is listening for a connection on. + +When the testsuite is running, lldb may use the pid to kill off a +debugserver that doesn't seem to be responding, etc. + +## qKillSpawnedProcess + +### Brief + +Kill a process running on the target system. + +### Example + +``` +receive: qKillSpawnedProcess:1337 +send: OK +``` +The request packet has the process ID in base 10. + +## qProcessInfoPID: + +### Brief + +Gather information about a process running on the target. + +### Example + +``` +receive: qProcessInfoPID:71964 +send: pid:71964;name:612e6f7574; +``` + +The request packet has the pid encoded in base 10. + +The reply has semicolon-separated `name:value` fields, two are +shown here. `pid` is base 10 encoded. `name` is ascii hex encoded. +lldb-server can reply with many additional fields, but this is probably +enough for the testsuite. + +## qfProcessInfo + +### Brief + +Search the process table for processes matching criteria, +respond with them in multiple packets. + +### Example + +``` +receive: qfProcessInfo:name_match:equals;name:6e6f70726f6365737365786973747377697468746869736e616d65; +send: pid:3500;name:612e6f7574; +``` + +The request packet has a criteria to search for, followed by +a specific name. + +| Key | Value | Description +| ------------ | --------- | ----------- +| `name` | ascii-hex | An ASCII hex string that contains the name of the process that will be matched. +| `name_match` | enum | One of: `equals`, `starts_with`, `ends_with`, `contains` or `regex` +| `pid` | integer | A string value containing the decimal process ID +| `parent_pid` | integer | A string value containing the decimal parent process ID +| `uid` | integer | A string value containing the decimal user ID +| `gid` | integer | A string value containing the decimal group ID +| `euid` | integer | A string value containing the decimal effective user ID +| `egid` | integer | A string value containing the decimal effective group ID +| `all_users` | bool | A boolean value that specifies if processes should be listed for all users, not just the user that the platform is running as +| `triple` | ascii-hex | An ASCII hex target triple string (`x86_64`, `x86_64-apple-macosx`, `armv7-apple-ios`) + +If no criteria is given, `qfProcessInfo` will request a list of every process. + +The lldb testsuite currently only uses `name_match:equals` and the +no-criteria mode to list every process. + +The response should include any information about the process that +can be retrieved in semicolon-separated `name:value` fields. +In this example, `pid` is base 10, `name` is ASCII hex encoded. +The testsuite seems to only require these two. + +This packet only responds with one process. To get further matches to +the search, `qsProcessInfo` should be sent. + +If no process match is found, `Exx` should be returned. + +Sample packet/response: +``` +send packet: $qfProcessInfo#00 +read packet: $pid:60001;ppid:59948;uid:7746;gid:11;euid:7746;egid:11;name:6c6c6462;triple:7838365f36342d6170706c652d6d61636f7378;#00 +send packet: $qsProcessInfo#00 +read packet: $pid:59992;ppid:192;uid:7746;gid:11;euid:7746;egid:11;name:6d64776f726b6572;triple:7838365f36342d6170706c652d6d61636f7378;#00 +send packet: $qsProcessInfo#00 +read packet: $E04#00 +``` + +## qsProcessInfo + +### Brief + +Return the next process info found by the most recent `qfProcessInfo:` +packet. + +### Example + +Continues to return the results of the `qfProcessInfo`. Once all matches +have been sent, `Exx` is returned to indicate end of matches. + +## qPathComplete + +### Brief + +Get a list of matched disk files/directories by passing a boolean flag +and a partial path. + +### Example + +``` +receive: qPathComplete:0,6d61696e +send: M6d61696e2e637070 +receive: qPathComplete:1,746573 +send: M746573742f,74657374732f +``` + +If the first argument is zero, the result should contain all +files (including directories) starting with the given path. If the +argument is one, the result should contain only directories. + +The result should be a comma-separated list of hex-encoded paths. +Paths denoting a directory should end with a directory separator (`/` or `\`). + +## vFile:size + +### Brief + +Get the size of a file on the target system, filename in ASCII hex encoding. + +### Example + +``` +receive: vFile:size:2f746d702f61 +send: Fc008 +``` + +response is `F` followed by the file size in base 16. +`F-1,errno` with the errno if an error occurs, base 16. + +## vFile:mode + +### Brief + +Get the mode bits of a file on the target system, filename in ASCII hex. + +### Example + +``` +receive: vFile:mode:2f746d702f61 +send: F1ed +``` + +response is `F` followed by the mode bits in base 16, this `0x1ed` would +correspond to `0755` in octal. +`F-1,errno` with the errno if an error occurs, base 16. + +## vFile:unlink + +### Brief + +Remove a file on the target system. + +### Example + +``` +receive: vFile:unlink:2f746d702f61 +send: F0 +``` + +Argument is a file path in ascii-hex encoding. + +Response is `F` plus the return value of `unlink()` in base 16 encoding. +If unlink failed, the return value may be followed by a comma and the value of +errno in base 16 encoding. + +## vFile:symlink + +### Brief + +Create a symbolic link (symlink, soft-link) on the target system. + +### Example + +``` +receive: vFile:symlink:, +send: F0,0 +``` + +Argument file paths are in ascii-hex encoding. +Response is `F` plus the return value of `symlink()`, base 16 encoding, +optionally followed by the value of errno if it failed, also base 16. + +## vFile:chmod / qPlatform_chmod + +### Brief + +Change the permission mode bits on a file on the target + +### Example + +``` +receive: vFile:chmod:180,2f746d702f61 +send: F0 +``` + +Arguments are the mode bits to set, base 16, and a file path in +ascii-hex encoding. +Response is `F` plus the return value of `chmod()`, base 16 encoding. + +These 2 packets do the same thing, it is not known why we ended up with 2. + +## vFile:chmod + +### Brief + +Change the permission mode bits on a file on the target. + +### Example + +``` +receive: vFile:chmod:180,2f746d702f61 +send: F0 +``` + +Arguments are the mode bits to set, base 16, and a file path in +ascii-hex encoding. +Response is `F` plus the return value of `chmod()`, base 10 encoding. + +## vFile:open + +### Brief + +Open a file on the remote system and return the file descriptor of it. + +### Example + +``` +receive: vFile:open:2f746d702f61,00000001,00000180 +send: F8 +``` + +request packet has the fields: + 1. ASCII hex encoded filename + 2. Flags passed to the open call, base 16. + Note that these are not the `oflags` that `open(2)` takes, but + are the constant values in `enum OpenOptions` from LLDB's + [`File.h`](https://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Host/File.h). + 3. Mode bits, base 16 + +response is `F` followed by the opened file descriptor in base 16. +`F-1,errno` with the errno if an error occurs, base 16. + +## vFile:close + +### Brief + +Close a previously opened file descriptor. + +### Example + +``` +receive: vFile:close:7 +send: F0 +``` + +File descriptor is in base 16. `F-1,errno` with the errno if an error occurs, +errno is base 16. + +## vFile:pread + +### Brief + +Read data from an opened file descriptor. + +### Example + +``` +receive: vFile:pread:7,1024,0 +send: F4;a'b\00 +``` + +Request packet has the fields: + 1. File descriptor, base 16 + 2. Number of bytes to be read, base 16 + 3. Offset into file to start from, base 16 + +Response is `F`, followed by the number of bytes read (base 16 encoded), a +semicolon, followed by the data in the binary-escaped-data encoding. + +## vFile:pwrite + +### Brief + +Write data to a previously opened file descriptor. + +### Example + +``` +receive: vFile:pwrite:8,0,\cf\fa\ed\fe\0c\00\00 +send: F1024 +``` + +Request packet has the fields: + 1. File descriptor, base 16 + 2. Offset into file to start from, base 16 + 3. binary-escaped-data to be written + +Response is `F`, followed by the number of bytes written (base 16 encoded). + +## Launching Processes + +Finally, the platform must be able to launch processes so that debugserver +can attach to them. To do this, the following packets should be handled: +* `QSetDisableASLR` +* `QSetDetachOnError` +* `QSetSTDOUT` +* `QSetSTDERR` +* `QSetSTDIN` +* `QEnvironment` +* `QEnvironmentHexEncoded` +* `A` +* `qLaunchSuccess` +* `qProcessInfo` + +Most of these are documented in the standard gdb-remote protocol +and/or LLDB's [GDB Remote Protocol Extensions](lldbgdbremote). -- GitLab From fe47e8ff3ae7fc8975eaade6bfa6679737c28b93 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Thu, 25 Apr 2024 15:45:16 +0800 Subject: [PATCH 068/733] [NFC] [ASTUnit] [Serialization] Transalte local decl ID to global decl ID before consuming Discovered from https://github.com/llvm/llvm-project/commit/d86cc73bbfd9a22d9a0d498d72c9b2ee235128e9. There is a potential issue of using DeclID in ASTUnit. ASTUnit may record the declaration ID from ASTWriter. And after loading the preamble, the ASTUnit may consume the recorded declaration ID directly in ExternalASTSource. This is not good. According to the design, all local declaration ID consumed in ASTReader need to be translated by `ASTReader::getGlobaldeclID()`. This will be problematic if we changed the encodings of declaration IDs or if we make preamble to work more complexly. --- clang/lib/Frontend/ASTUnit.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 2f75313e8a4c..1b93588553a2 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1467,13 +1467,12 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() { std::vector Resolved; Resolved.reserve(TopLevelDeclsInPreamble.size()); - ExternalASTSource &Source = *getASTContext().getExternalSource(); + // The module file of the preamble. + serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule(); for (const auto TopLevelDecl : TopLevelDeclsInPreamble) { // Resolve the declaration ID to an actual declaration, possibly // deserializing the declaration in the process. - // - // FIMXE: We shouldn't convert a LocalDeclID to GlobalDeclID directly. - if (Decl *D = Source.GetExternalDecl(GlobalDeclID(TopLevelDecl.get()))) + if (Decl *D = Reader->GetDecl(Reader->getGlobalDeclID(MF, TopLevelDecl))) Resolved.push_back(D); } TopLevelDeclsInPreamble.clear(); -- GitLab From 7bc0177fc73a75f5195b09ee9d46579eb43c79c4 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Thu, 25 Apr 2024 10:25:31 +0100 Subject: [PATCH 069/733] [flang] run character conversion pass on all top level ops (#89910) See RFC: https://discourse.llvm.org/t/rfc-add-an-interface-for-top-level-container-operations Some of the changes are from moving declaration and definition of the constructor function into tablegen (as requested in code review when altering another pass). --- flang/include/flang/Optimizer/Transforms/Passes.h | 1 - flang/include/flang/Optimizer/Transforms/Passes.td | 1 - flang/include/flang/Tools/CLOptions.inc | 2 +- flang/lib/Optimizer/Transforms/CharacterConversion.cpp | 7 +++---- flang/test/Driver/bbc-mlir-pass-pipeline.f90 | 5 +++++ flang/test/Driver/mlir-debug-pass-pipeline.f90 | 5 +++++ flang/test/Driver/mlir-pass-pipeline.f90 | 5 +++++ flang/test/Fir/basic-program.fir | 5 +++++ 8 files changed, 24 insertions(+), 7 deletions(-) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index 402f212387e4..0af32f4f8bc8 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -52,7 +52,6 @@ namespace fir { std::unique_ptr createAffineDemotionPass(); std::unique_ptr createArrayValueCopyPass(fir::ArrayValueCopyOptions options = {}); -std::unique_ptr createCharacterConversionPass(); std::unique_ptr createExternalNameConversionPass(); std::unique_ptr createExternalNameConversionPass(bool appendUnderscore); diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index 88e4321e5b2b..d64b33211b25 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -127,7 +127,6 @@ def CharacterConversion : Pass<"character-conversion"> { By default the translation is to naively zero-extend or truncate a code point to fit the destination size. }]; - let constructor = "::fir::createCharacterConversionPass()"; let dependentDialects = [ "fir::FIROpsDialect" ]; let options = [ Option<"useRuntimeCalls", "use-runtime-calls", diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index a9d8ebc84e2e..952805f60495 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -243,7 +243,7 @@ inline void createDefaultFIROptimizerPassPipeline( config.enableRegionSimplification = false; pm.addPass(mlir::createCSEPass()); fir::addAVC(pm, pc.OptLevel); - pm.addNestedPass(fir::createCharacterConversionPass()); + addNestedPassToAllTopLevelOperations(pm, fir::createCharacterConversion); pm.addPass(mlir::createCanonicalizerPass(config)); pm.addPass(fir::createSimplifyRegionLitePass()); if (pc.OptLevel.isOptimizingForSpeed()) { diff --git a/flang/lib/Optimizer/Transforms/CharacterConversion.cpp b/flang/lib/Optimizer/Transforms/CharacterConversion.cpp index 2e8fc42487a5..87ea72dbca9b 100644 --- a/flang/lib/Optimizer/Transforms/CharacterConversion.cpp +++ b/flang/lib/Optimizer/Transforms/CharacterConversion.cpp @@ -102,6 +102,9 @@ public: class CharacterConversion : public fir::impl::CharacterConversionBase { public: + using fir::impl::CharacterConversionBase< + CharacterConversion>::CharacterConversionBase; + void runOnOperation() override { CharacterConversionOptions clOpts{useRuntimeCalls.getValue()}; if (clOpts.runtimeName.empty()) { @@ -130,7 +133,3 @@ public: } }; } // end anonymous namespace - -std::unique_ptr fir::createCharacterConversionPass() { - return std::make_unique(); -} diff --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90 index 2ee832e3c57a..7a35e26dc478 100644 --- a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 +++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90 @@ -17,9 +17,14 @@ end program ! CHECK-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! CHECK-NEXT: (S) 0 num-dce'd - Number of operations DCE'd +! CHECK-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction'] +! CHECK-NEXT: 'fir.global' Pipeline +! CHECK-NEXT: CharacterConversion ! CHECK-NEXT: 'func.func' Pipeline ! CHECK-NEXT: ArrayValueCopy ! CHECK-NEXT: CharacterConversion +! CHECK-NEXT: 'omp.declare_reduction' Pipeline +! CHECK-NEXT: CharacterConversion ! CHECK-NEXT: Canonicalizer ! CHECK-NEXT: SimplifyRegionLite diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90 index 06957604d7aa..28d70bc15264 100644 --- a/flang/test/Driver/mlir-debug-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90 @@ -39,9 +39,14 @@ end program ! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd +! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction'] +! ALL-NEXT: 'fir.global' Pipeline +! ALL-NEXT: CharacterConversion ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: ArrayValueCopy ! ALL-NEXT: CharacterConversion +! ALL-NEXT: 'omp.declare_reduction' Pipeline +! ALL-NEXT: CharacterConversion ! ALL-NEXT: Canonicalizer ! ALL-NEXT: SimplifyRegionLite diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90 index 0272739aba4d..41f3c203e435 100644 --- a/flang/test/Driver/mlir-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-pass-pipeline.f90 @@ -28,9 +28,14 @@ end program ! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd +! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction'] +! ALL-NEXT: 'fir.global' Pipeline +! ALL-NEXT: CharacterConversion ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: ArrayValueCopy ! ALL-NEXT: CharacterConversion +! ALL-NEXT: 'omp.declare_reduction' Pipeline +! ALL-NEXT: CharacterConversion ! ALL-NEXT: Canonicalizer ! ALL-NEXT: SimplifyRegionLite diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir index d4826dd2e476..7508963a3d51 100644 --- a/flang/test/Fir/basic-program.fir +++ b/flang/test/Fir/basic-program.fir @@ -34,9 +34,14 @@ func.func @_QQmain() { // PASSES-NEXT: (S) 0 num-cse'd - Number of operations CSE'd // PASSES-NEXT: (S) 0 num-dce'd - Number of operations DCE'd +// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction'] +// PASSES-NEXT: 'fir.global' Pipeline +// PASSES-NEXT: CharacterConversion // PASSES-NEXT: 'func.func' Pipeline // PASSES-NEXT: ArrayValueCopy // PASSES-NEXT: CharacterConversion +// PASSES-NEXT: 'omp.declare_reduction' Pipeline +// PASSES-NEXT: CharacterConversion // PASSES-NEXT: Canonicalizer // PASSES-NEXT: SimplifyRegionLite -- GitLab From 92f4f0b061651fc57e8434f0d651851878e0eab5 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Thu, 25 Apr 2024 10:25:46 +0100 Subject: [PATCH 070/733] [flang][NFC] Use tablegen to create simplifyRegionLite constructor (#89957) This is a ModuleOp pass anyway so it doesn't need to be run on particular top level operations. --- flang/include/flang/Optimizer/Transforms/Passes.h | 1 - flang/include/flang/Optimizer/Transforms/Passes.td | 1 - flang/include/flang/Tools/CLOptions.inc | 6 +++--- flang/lib/Optimizer/Transforms/SimplifyRegionLite.cpp | 4 ---- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index 0af32f4f8bc8..fc7c781aadd9 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -68,7 +68,6 @@ std::unique_ptr createLoopVersioningPass(); std::unique_ptr createMemoryAllocationPass(bool dynOnHeap, std::size_t maxStackSize); std::unique_ptr createAnnotateConstantOperandsPass(); -std::unique_ptr createSimplifyRegionLitePass(); std::unique_ptr createAlgebraicSimplificationPass(); std::unique_ptr createAlgebraicSimplificationPass(const mlir::GreedyRewriteConfig &config); diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index d64b33211b25..901e7590a85f 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -286,7 +286,6 @@ def SimplifyRegionLite : Pass<"simplify-region-lite", "mlir::ModuleOp"> { let description = [{ Run region DCE and erase unreachable blocks in regions. }]; - let constructor = "::fir::createSimplifyRegionLitePass()"; } def AlgebraicSimplification : Pass<"flang-algebraic-simplification"> { diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index 952805f60495..da993fec7f7b 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -245,7 +245,7 @@ inline void createDefaultFIROptimizerPassPipeline( fir::addAVC(pm, pc.OptLevel); addNestedPassToAllTopLevelOperations(pm, fir::createCharacterConversion); pm.addPass(mlir::createCanonicalizerPass(config)); - pm.addPass(fir::createSimplifyRegionLitePass()); + pm.addPass(fir::createSimplifyRegionLite()); if (pc.OptLevel.isOptimizingForSpeed()) { // These passes may increase code size. pm.addPass(fir::createSimplifyIntrinsicsPass()); @@ -267,7 +267,7 @@ inline void createDefaultFIROptimizerPassPipeline( llvm::StringMap pipelines; pm.addPass(mlir::createInlinerPass( pipelines, addCanonicalizerPassWithoutRegionSimplification)); - pm.addPass(fir::createSimplifyRegionLitePass()); + pm.addPass(fir::createSimplifyRegionLite()); pm.addPass(mlir::createCSEPass()); // Polymorphic types @@ -281,7 +281,7 @@ inline void createDefaultFIROptimizerPassPipeline( pm.addPass(mlir::createConvertSCFToCFPass()); pm.addPass(mlir::createCanonicalizerPass(config)); - pm.addPass(fir::createSimplifyRegionLitePass()); + pm.addPass(fir::createSimplifyRegionLite()); pm.addPass(mlir::createCSEPass()); } diff --git a/flang/lib/Optimizer/Transforms/SimplifyRegionLite.cpp b/flang/lib/Optimizer/Transforms/SimplifyRegionLite.cpp index 3fe6bed12cf4..7d1f86f8cee9 100644 --- a/flang/lib/Optimizer/Transforms/SimplifyRegionLite.cpp +++ b/flang/lib/Optimizer/Transforms/SimplifyRegionLite.cpp @@ -45,7 +45,3 @@ void SimplifyRegionLitePass::runOnOperation() { (void)mlir::eraseUnreachableBlocks(rewriter, regions); (void)mlir::runRegionDCE(rewriter, regions); } - -std::unique_ptr fir::createSimplifyRegionLitePass() { - return std::make_unique(); -} -- GitLab From 81442f8d97e50f5d8c33136b105b478a8137685e Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Thu, 25 Apr 2024 10:26:05 +0100 Subject: [PATCH 071/733] [flang][NFC] Use tablegen to create SimplifyIntrinsics constructor (#89963) This pass runs on ModuleOp, internally walking all func::CallOps so it shouldn't need anything special to work on other top level operations. --- flang/include/flang/Optimizer/Transforms/Passes.h | 1 - flang/include/flang/Optimizer/Transforms/Passes.td | 1 - flang/include/flang/Tools/CLOptions.inc | 2 +- flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp | 6 +++--- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index fc7c781aadd9..fd7a4a3883c9 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -60,7 +60,6 @@ std::unique_ptr createPromoteToAffinePass(); std::unique_ptr createMemoryAllocationPass(); std::unique_ptr createStackArraysPass(); std::unique_ptr createAliasTagsPass(); -std::unique_ptr createSimplifyIntrinsicsPass(); std::unique_ptr createAddDebugInfoPass(fir::AddDebugInfoOptions options = {}); std::unique_ptr createLoopVersioningPass(); diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index 901e7590a85f..c3d5c336af40 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -224,7 +224,6 @@ def SimplifyIntrinsics : Pass<"simplify-intrinsics", "mlir::ModuleOp"> { simplified function. The simplified function is added to the current module. This function can be inlined by a general purpose inlining pass. }]; - let constructor = "::fir::createSimplifyIntrinsicsPass()"; let options = [ Option<"enableExperimental", "enable-experimental", "bool", diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc index da993fec7f7b..f24716333d9a 100644 --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -248,7 +248,7 @@ inline void createDefaultFIROptimizerPassPipeline( pm.addPass(fir::createSimplifyRegionLite()); if (pc.OptLevel.isOptimizingForSpeed()) { // These passes may increase code size. - pm.addPass(fir::createSimplifyIntrinsicsPass()); + pm.addPass(fir::createSimplifyIntrinsics()); pm.addPass(fir::createAlgebraicSimplificationPass(config)); } diff --git a/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp b/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp index f7820b6b8170..a4f2f5238e40 100644 --- a/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp +++ b/flang/lib/Optimizer/Transforms/SimplifyIntrinsics.cpp @@ -72,6 +72,9 @@ class SimplifyIntrinsicsPass mlir::Type elementType)>; public: + using fir::impl::SimplifyIntrinsicsBase< + SimplifyIntrinsicsPass>::SimplifyIntrinsicsBase; + /// Generate a new function implementing a simplified version /// of a Fortran runtime function defined by \p basename name. /// \p typeGenerator is a callback that generates the new function's type. @@ -1387,6 +1390,3 @@ void SimplifyIntrinsicsPass::getDependentDialects( // LLVM::LinkageAttr creation requires that LLVM dialect is loaded. registry.insert(); } -std::unique_ptr fir::createSimplifyIntrinsicsPass() { - return std::make_unique(); -} -- GitLab From 87ec4ab72cb3ae27ac08d040b2825ee01214fe75 Mon Sep 17 00:00:00 2001 From: Orlando Cazalet-Hyams Date: Thu, 25 Apr 2024 10:34:32 +0100 Subject: [PATCH 072/733] [Clang] Fall back to DW_TAG_typedef for instantiation dependent template aliases (#90032) Workaround for issue #89774 until it can be properly fixed. When `-gtemplate-alias` is specified Clang emits a DW_TAG_template_alias for template aliases. This patch avoids an assertion failure by falling back to the `-gno-template-alias` (default) behaviour, emitting a DW_TAG_typedef, if the alias is instantiation dependent. --- clang/lib/CodeGen/CGDebugInfo.cpp | 21 ++++++++++++++++++- .../CodeGenCXX/dependent-template-alias.cpp | 21 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGenCXX/dependent-template-alias.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 539ded5cca5e..787db3504874 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1372,7 +1372,26 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, SourceLocation Loc = AliasDecl->getLocation(); - if (CGM.getCodeGenOpts().DebugTemplateAlias) { + if (CGM.getCodeGenOpts().DebugTemplateAlias && + // The TemplateSpecializationType doesn't contain any instantiation + // information; dependent template arguments can't be resolved. For now, + // fall back to DW_TAG_typedefs for template aliases that are + // instantiation dependent, e.g.: + // ``` + // template + // using A = int; + // + // template + // struct S { + // using AA = A; // Instantiation dependent. + // AA aa; + // }; + // + // S<0> s; + // ``` + // S::AA's underlying type A is dependent on I so will be emitted as a + // DW_TAG_typedef. + !Ty->isInstantiationDependentType()) { auto ArgVector = ::GetTemplateArgs(TD, Ty); TemplateArgs Args = {TD->getTemplateParameters(), ArgVector}; diff --git a/clang/test/CodeGenCXX/dependent-template-alias.cpp b/clang/test/CodeGenCXX/dependent-template-alias.cpp new file mode 100644 index 000000000000..deb243f9fc88 --- /dev/null +++ b/clang/test/CodeGenCXX/dependent-template-alias.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -gtemplate-alias %s -gsimple-template-names=simple \ +// RUN: | FileCheck %s + +//// Check that -gtemplate-alias falls back to DW_TAG_typedef emission +//// for instantiation dependent type aliases. + +template +using A = int; + +template +struct S { + using AA = A; + AA aa; +}; + +S<0> s; + +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[AA:[0-9]+]], size: 32) +// CHECK: [[AA]] = !DIDerivedType(tag: DW_TAG_typedef, name: "AA", file: ![[#]], line: [[#]], baseType: ![[A:[0-9]+]]) +// CHECK: [[A]] = !DIDerivedType(tag: DW_TAG_typedef, name: "A", file: ![[#]], line: [[#]], baseType: ![[int:[0-9]+]]) +// CHECK: [[int]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -- GitLab From d5f2753067df89ed4c49d387deb0b3a6b59f8175 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 25 Apr 2024 10:44:36 +0100 Subject: [PATCH 073/733] [LAA] Tests with different strides where BTC can rule out dependence. Tests to add support for different strides with isSafeDependenceDistance as follow-up to https://github.com/llvm/llvm-project/pull/88039. --- ...es-safe-dep-due-to-backedge-taken-count.ll | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll diff --git a/llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll b/llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll new file mode 100644 index 000000000000..932129bbb957 --- /dev/null +++ b/llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll @@ -0,0 +1,156 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4 +; RUN: opt -passes='print' -disable-output %s 2>&1 | FileCheck %s + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + +define void @forward_dep_known_safe_due_to_backedge_taken_count(ptr %A) { +; CHECK-LABEL: 'forward_dep_known_safe_due_to_backedge_taken_count' +; CHECK-NEXT: loop: +; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop +; CHECK-NEXT: Unknown data dependence. +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Unknown: +; CHECK-NEXT: %l = load i32, ptr %gep.mul.2, align 4 -> +; CHECK-NEXT: store i32 %add, ptr %gep, align 4 +; CHECK-EMPTY: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Grouped accesses: +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: +; +entry: + %A.511= getelementptr inbounds i32, ptr %A, i64 511 + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] + %iv.mul.2 = shl nuw nsw i64 %iv, 1 + %gep.mul.2 = getelementptr inbounds i32, ptr %A.511, i64 %iv.mul.2 + %l = load i32, ptr %gep.mul.2, align 4 + %add = add nsw i32 %l, 5 + %gep = getelementptr inbounds i32, ptr %A, i64 %iv + store i32 %add, ptr %gep, align 4 + %iv.next = add nuw nsw i64 %iv, 1 + %exitcond.not = icmp eq i64 %iv.next, 256 + br i1 %exitcond.not, label %exit, label %loop + +exit: + ret void +} + +define void @forward_dep_not_known_safe_due_to_backedge_taken_count(ptr %A) { +; CHECK-LABEL: 'forward_dep_not_known_safe_due_to_backedge_taken_count' +; CHECK-NEXT: loop: +; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop +; CHECK-NEXT: Unknown data dependence. +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Unknown: +; CHECK-NEXT: %l = load i32, ptr %gep.mul.2, align 4 -> +; CHECK-NEXT: store i32 %add, ptr %gep, align 4 +; CHECK-EMPTY: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Grouped accesses: +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: +; +entry: + %A.510 = getelementptr inbounds i32, ptr %A, i64 510 + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] + %iv.mul.2 = shl nuw nsw i64 %iv, 1 + %gep.mul.2 = getelementptr inbounds i32, ptr %A.510, i64 %iv.mul.2 + %l = load i32, ptr %gep.mul.2, align 4 + %add = add nsw i32 %l, 5 + %gep = getelementptr inbounds i32, ptr %A, i64 %iv + store i32 %add, ptr %gep, align 4 + %iv.next = add nuw nsw i64 %iv, 1 + %exitcond.not = icmp eq i64 %iv.next, 256 + br i1 %exitcond.not, label %exit, label %loop + +exit: + ret void +} + +define void @unknown_dep_known_safe_due_to_backedge_taken_count(ptr %A) { +; CHECK-LABEL: 'unknown_dep_known_safe_due_to_backedge_taken_count' +; CHECK-NEXT: loop: +; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop +; CHECK-NEXT: Unknown data dependence. +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Unknown: +; CHECK-NEXT: %l = load i32, ptr %gep, align 4 -> +; CHECK-NEXT: store i32 %add, ptr %gep.mul.2, align 4 +; CHECK-EMPTY: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Grouped accesses: +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: +; +entry: + %A.511 = getelementptr inbounds i32, ptr %A, i64 511 + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] + %iv.mul.2 = shl nuw nsw i64 %iv, 1 + %gep = getelementptr inbounds i32, ptr %A, i64 %iv + %l = load i32, ptr %gep, align 4 + %add = add nsw i32 %l, 5 + %gep.mul.2 = getelementptr inbounds i32, ptr %A.511, i64 %iv.mul.2 + store i32 %add, ptr %gep.mul.2, align 4 + %iv.next = add nuw nsw i64 %iv, 1 + %exitcond.not = icmp eq i64 %iv.next, 256 + br i1 %exitcond.not, label %exit, label %loop + +exit: + ret void +} + +define void @unknown_dep_not_known_safe_due_to_backedge_taken_count(ptr %A) { +; CHECK-LABEL: 'unknown_dep_not_known_safe_due_to_backedge_taken_count' +; CHECK-NEXT: loop: +; CHECK-NEXT: Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop +; CHECK-NEXT: Unknown data dependence. +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Unknown: +; CHECK-NEXT: %l = load i32, ptr %gep, align 4 -> +; CHECK-NEXT: store i32 %add, ptr %gep.mul.2, align 4 +; CHECK-EMPTY: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Grouped accesses: +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: +; +entry: + %A.510 = getelementptr inbounds i32, ptr %A, i64 510 + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] + %iv.mul.2 = shl nuw nsw i64 %iv, 1 + %gep = getelementptr inbounds i32, ptr %A, i64 %iv + %l = load i32, ptr %gep, align 4 + %add = add nsw i32 %l, 5 + %gep.mul.2 = getelementptr inbounds i32, ptr %A.510, i64 %iv.mul.2 + store i32 %add, ptr %gep.mul.2, align 4 + %iv.next = add nuw nsw i64 %iv, 1 + %exitcond.not = icmp eq i64 %iv.next, 256 + br i1 %exitcond.not, label %exit, label %loop + +exit: + ret void +} -- GitLab From 2125080fd5e12d54b745e36db6b68ec8a1377c33 Mon Sep 17 00:00:00 2001 From: Wang Pengcheng Date: Thu, 25 Apr 2024 17:56:26 +0800 Subject: [PATCH 074/733] [RISCV][NFC] Undef CASE_RVV_OPCODE* macros after using --- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index dac47d6f4154..5c1f154efa99 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -3152,6 +3152,16 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI, return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2); } +#undef CASE_RVV_OPCODE_UNMASK_LMUL +#undef CASE_RVV_OPCODE_MASK_LMUL +#undef CASE_RVV_OPCODE_LMUL +#undef CASE_RVV_OPCODE_UNMASK_WIDEN +#undef CASE_RVV_OPCODE_UNMASK +#undef CASE_RVV_OPCODE_MASK_WIDEN +#undef CASE_RVV_OPCODE_MASK +#undef CASE_RVV_OPCODE_WIDEN +#undef CASE_RVV_OPCODE + #undef CASE_VMA_OPCODE_COMMON #undef CASE_VMA_OPCODE_LMULS_M1 #undef CASE_VMA_OPCODE_LMULS_MF2 -- GitLab From 2c5d7a888589a608a4cd6adc34f19a65dc4551af Mon Sep 17 00:00:00 2001 From: Jannik Silvanus <37809848+jasilvanus@users.noreply.github.com> Date: Thu, 25 Apr 2024 12:47:43 +0200 Subject: [PATCH 075/733] [clang-format] Remove YAML hack to emit a BasedOnStyle comment (#89228) When serializing a formatting style to YAML, we were emitting a comment `# BasedOnStyle: